From 37f6897b0c2413302675a576f3b46ad3fd218e1b Mon Sep 17 00:00:00 2001 From: tsnobip Date: Fri, 5 Jun 2026 15:02:24 +0200 Subject: [PATCH 1/6] make @returnType work with setof --- .../src/plugins/PgCustomTypeFieldPlugin.ts | 23 +- .../__tests__/kitchen-sink-schema.sql | 13 + .../return-type-computed-column-setof.json5 | 308 ++++++++++++++++++ .../return-type-computed-column-setof.mermaid | 102 ++++++ .../return-type-computed-column-setof.sql | 36 ++ ...rn-type-computed-column-setof.test.graphql | 35 ++ .../schema/v4/defaultOptions.1.export.mjs | 8 +- .../schema/v4/defaultOptions.1.graphql | 8 +- .../defaultOptions.subscriptions.1.export.mjs | 8 +- .../v4/defaultOptions.subscriptions.1.graphql | 8 +- .../foreignKey-smart-tag-autofix.1.export.mjs | 6 +- .../v4/foreignKey-smart-tag-autofix.1.graphql | 6 +- .../v4/foreignKey-smart-tag-good.1.export.mjs | 6 +- .../v4/foreignKey-smart-tag-good.1.graphql | 6 +- ...ash-with-tags-file-workaround.1.export.mjs | 8 +- ...-clash-with-tags-file-workaround.1.graphql | 8 +- .../schema/v4/function-clash.1.export.mjs | 8 +- .../schema/v4/function-clash.1.graphql | 8 +- .../__tests__/schema/v4/indexes.1.export.mjs | 8 +- .../__tests__/schema/v4/indexes.1.graphql | 8 +- .../v4/inflect-builtin-lowercase.1.export.mjs | 12 +- .../v4/inflect-builtin-lowercase.1.graphql | 12 +- .../schema/v4/inflect-core.1.export.mjs | 12 +- .../schema/v4/inflect-core.1.graphql | 12 +- .../schema/v4/noDefaultMutations.1.export.mjs | 6 +- .../schema/v4/noDefaultMutations.1.graphql | 6 +- .../schema/v4/pgStrictFunctions.1.export.mjs | 8 +- .../schema/v4/pgStrictFunctions.1.graphql | 8 +- .../polymorphic-auto-add-types.1.export.mjs | 252 +++++++++++++- .../v4/polymorphic-auto-add-types.1.graphql | 133 ++++++++ .../schema/v4/polymorphic.1.export.mjs | 252 +++++++++++++- .../__tests__/schema/v4/polymorphic.1.graphql | 133 ++++++++ .../schema/v4/rbac.ignore.1.export.mjs | 8 +- .../__tests__/schema/v4/rbac.ignore.1.graphql | 8 +- .../__tests__/schema/v4/relay1.1.export.mjs | 6 +- .../__tests__/schema/v4/relay1.1.graphql | 6 +- .../schema/v4/simple-collections.1.export.mjs | 6 +- .../schema/v4/simple-collections.1.graphql | 6 +- .../schema/v4/simplePrint.export.mjs | 8 +- .../__tests__/schema/v4/simplePrint.graphql | 8 +- .../schema/v4/skipNodePlugin.1.export.mjs | 8 +- .../schema/v4/skipNodePlugin.1.graphql | 8 +- .../skipNodePlugin.polymorphic.1.export.mjs | 252 +++++++++++++- .../v4/skipNodePlugin.polymorphic.1.graphql | 133 ++++++++ .../schema/v5/skipNodePlugin.1.export.mjs | 8 +- .../schema/v5/skipNodePlugin.1.graphql | 8 +- .../skipNodePlugin.polymorphic.1.export.mjs | 200 +++++++++++- .../v5/skipNodePlugin.polymorphic.1.graphql | 103 ++++++ 48 files changed, 2047 insertions(+), 196 deletions(-) create mode 100644 postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.json5 create mode 100644 postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.mermaid create mode 100644 postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.sql create mode 100644 postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.test.graphql diff --git a/graphile-build/graphile-build-pg/src/plugins/PgCustomTypeFieldPlugin.ts b/graphile-build/graphile-build-pg/src/plugins/PgCustomTypeFieldPlugin.ts index a929679573..ca1ebf8b67 100644 --- a/graphile-build/graphile-build-pg/src/plugins/PgCustomTypeFieldPlugin.ts +++ b/graphile-build/graphile-build-pg/src/plugins/PgCustomTypeFieldPlugin.ts @@ -1332,6 +1332,10 @@ function modFields( }); const namedType = build.graphql.getNamedType(type!); + const preferredConnectionTypeName = + resource.extensions?.tags?.returnType && namedType + ? inflection.connectionType(namedType.name) + : null; const connectionTypeName = shouldUseCustomConnection(resource) ? resource.codec.attributes ? inflection.recordFunctionConnectionType({ @@ -1340,11 +1344,13 @@ function modFields( : inflection.scalarFunctionConnectionType({ resource, }) - : resource.codec.attributes - ? inflection.tableConnectionType(resource.codec) - : namedType - ? inflection.connectionType(namedType.name) - : null; + : preferredConnectionTypeName + ? preferredConnectionTypeName + : resource.codec.attributes + ? inflection.tableConnectionType(resource.codec) + : namedType + ? inflection.connectionType(namedType.name) + : null; const ConnectionType = connectionTypeName ? build.getOutputTypeByName(connectionTypeName) @@ -1368,9 +1374,10 @@ function modFields( { description: resource.description ?? - `Reads and enables pagination through a set of \`${inflection.tableType( - resource.codec, - )}\`.`, + `Reads and enables pagination through a set of \`${ + namedType?.name ?? + inflection.tableType(resource.codec) + }\`.`, type: build.nullableIf( isRootQuery ?? false, ConnectionType, diff --git a/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql b/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql index 861aa8eb85..99bc9bb0db 100644 --- a/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql +++ b/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql @@ -1445,6 +1445,19 @@ returns setof polymorphic.single_table_items as $$ select * from polymorphic.single_table_items $$ language sql stable; +create function polymorphic.single_table_items_topics( + sti polymorphic.single_table_items +) +returns setof polymorphic.single_table_items as $$ + select * + from polymorphic.single_table_items + where type = 'TOPIC' + order by id asc; +$$ language sql stable; +comment on function polymorphic.single_table_items_topics( + polymorphic.single_table_items +) is '@returnType SingleTableTopic'; + comment on constraint single_table_items_root_topic_fkey on polymorphic.single_table_items is $$ @behavior -* $$; diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.json5 b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.json5 new file mode 100644 index 0000000000..982789d683 --- /dev/null +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.json5 @@ -0,0 +1,308 @@ +{ + __type: { + fields: [ + { + name: "nodeId", + type: { + name: null, + ofType: { + name: "ID", + }, + }, + }, + { + name: "meaningOfLife", + type: { + name: "Int", + ofType: null, + }, + }, + { + name: "topics", + type: { + name: null, + ofType: { + name: "SingleTableTopicConnection", + }, + }, + }, + { + name: "topicsList", + type: { + name: null, + ofType: { + name: "SingleTableTopic", + }, + }, + }, + { + name: "id", + type: { + name: null, + ofType: { + name: "Int", + }, + }, + }, + { + name: "type", + type: { + name: null, + ofType: { + name: "ItemType", + }, + }, + }, + { + name: "parentId", + type: { + name: "Int", + ofType: null, + }, + }, + { + name: "rootTopicId", + type: { + name: "Int", + ofType: null, + }, + }, + { + name: "authorId", + type: { + name: null, + ofType: { + name: "Int", + }, + }, + }, + { + name: "position", + type: { + name: null, + ofType: { + name: "BigInt", + }, + }, + }, + { + name: "createdAt", + type: { + name: null, + ofType: { + name: "Datetime", + }, + }, + }, + { + name: "updatedAt", + type: { + name: null, + ofType: { + name: "Datetime", + }, + }, + }, + { + name: "isExplicitlyArchived", + type: { + name: null, + ofType: { + name: "Boolean", + }, + }, + }, + { + name: "archivedAt", + type: { + name: "Datetime", + ofType: null, + }, + }, + { + name: "subject", + type: { + name: "String", + ofType: null, + }, + }, + { + name: "description", + type: { + name: "String", + ofType: null, + }, + }, + { + name: "note", + type: { + name: "String", + ofType: null, + }, + }, + { + name: "priorityId", + type: { + name: "Int", + ofType: null, + }, + }, + { + name: "personByAuthorId", + type: { + name: "Person", + ofType: null, + }, + }, + { + name: "singleTableItemByParentId", + type: { + name: "SingleTableItem", + ofType: null, + }, + }, + { + name: "priorityByPriorityId", + type: { + name: "Priority", + ofType: null, + }, + }, + { + name: "singleTableItemsByParentId", + type: { + name: null, + ofType: { + name: "SingleTableItemsConnection", + }, + }, + }, + { + name: "singleTableItemsByParentIdList", + type: { + name: null, + ofType: { + name: null, + }, + }, + }, + { + name: "singleTableItemRelationsByChildId", + type: { + name: null, + ofType: { + name: "SingleTableItemRelationsConnection", + }, + }, + }, + { + name: "singleTableItemRelationsByChildIdList", + type: { + name: null, + ofType: { + name: null, + }, + }, + }, + { + name: "singleTableItemRelationsByParentId", + type: { + name: null, + ofType: { + name: "SingleTableItemRelationsConnection", + }, + }, + }, + { + name: "singleTableItemRelationsByParentIdList", + type: { + name: null, + ofType: { + name: null, + }, + }, + }, + { + name: "singleTableItemRelationCompositePksByChildId", + type: { + name: null, + ofType: { + name: "SingleTableItemRelationCompositePksConnection", + }, + }, + }, + { + name: "singleTableItemRelationCompositePksByChildIdList", + type: { + name: null, + ofType: { + name: null, + }, + }, + }, + { + name: "singleTableItemRelationCompositePksByParentId", + type: { + name: null, + ofType: { + name: "SingleTableItemRelationCompositePksConnection", + }, + }, + }, + { + name: "singleTableItemRelationCompositePksByParentIdList", + type: { + name: null, + ofType: { + name: null, + }, + }, + }, + { + name: "rootTopic", + type: { + name: "SingleTableTopic", + ofType: null, + }, + }, + ], + }, + allSingleTableItems: { + nodes: [ + { + id: 4, + type: "POST", + topics: { + nodes: [ + { + id: 1, + title: "PostGraphile version 5", + }, + { + id: 2, + title: "Temporary test topic", + }, + ], + }, + topicsList: [ + { + id: 1, + title: "PostGraphile version 5", + }, + { + id: 2, + title: "Temporary test topic", + }, + { + id: 10, + title: "Notes", + }, + { + id: 11, + title: "Other aims", + }, + ], + }, + ], + }, +} diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.mermaid b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.mermaid new file mode 100644 index 0000000000..388e3cd4ff --- /dev/null +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.mermaid @@ -0,0 +1,102 @@ +%%{init: {'themeVariables': { 'fontSize': '12px'}}}%% +graph TD + classDef path fill:#eee,stroke:#000,color:#000 + classDef plan fill:#fff,stroke-width:1px,color:#000 + classDef itemplan fill:#fff,stroke-width:2px,color:#000 + classDef unbatchedplan fill:#dff,stroke-width:1px,color:#000 + classDef sideeffectplan fill:#fcc,stroke-width:2px,color:#000 + classDef bucket fill:#f6f6f6,color:#000,stroke-width:2px,text-align:left + + subgraph "Buckets for queries/polymorphic/return-type-computed-column-setof" + Bucket0("Bucket 0 (root)

1:
ᐳ: 6, 11, 12, 60, 61, 7, 13, 15
2: PgSelect[10]
3: Connection[14]
4: ConnectionItems[17]"):::bucket + Bucket1("Bucket 1 (nullableBoundary)
Deps: 14, 17, 13, 61

ROOT Connectionᐸ10ᐳ[14]"):::bucket + Bucket3("Bucket 3 (listItem)
Deps: 13, 61

ROOT __Item{3}ᐸ17ᐳ[20]"):::bucket + Bucket4("Bucket 4 (polymorphic)
__typename: Lambda[26]
Deps: 21, 13, 61, 26, 22, 25

1: 43, 47
ᐳ: PgClassExpression[38]
2: PgSelect[39], PgSelect[45]
3: Connection[44], PgSelectRows[48]
4: ConnectionItems[51]"):::bucket + Bucket5("Bucket 5 (listItem)

ROOT __Item{5}ᐸ48ᐳ[49]"):::bucket + Bucket6("Bucket 6 (nullableBoundary)
Deps: 50

ROOT PgSelectSingle{5}ᐸsingle_table_items_topicsᐳ[50]"):::bucket + Bucket8("Bucket 8 (listItem)

ROOT __Item{8}ᐸ51ᐳ[54]"):::bucket + Bucket9("Bucket 9 (nullableBoundary)
Deps: 55

ROOT PgSelectSingle{8}ᐸsingle_table_items_topicsᐳ[55]"):::bucket + end + Bucket0 --> Bucket1 + Bucket1 --> Bucket3 + Bucket3 --> Bucket4 + Bucket4 --> Bucket5 & Bucket8 + Bucket5 --> Bucket6 + Bucket8 --> Bucket9 + + %% plan dependencies + __InputObject7{{"__InputObject[7∈0] ➊
More deps:
- Constantᐸ4ᐳ[60]
- Constantᐸundefinedᐳ[6]"}}:::plan + PgSelect10[["PgSelect[10∈0] ➊
ᐸsingle_table_itemsᐳ
More deps:
- Object[13]"]]:::plan + ApplyInput15{{"ApplyInput[15∈0] ➊"}}:::plan + ApplyInput15 --> PgSelect10 + Object13{{"Object[13∈0] ➊
ᐸ{pgSettings,withPgClient}ᐳ
Dependents: 3"}}:::plan + Access11{{"Access[11∈0] ➊
ᐸ2.pgSettingsᐳ"}}:::plan + Access12{{"Access[12∈0] ➊
ᐸ2.withPgClientᐳ"}}:::plan + Access11 & Access12 --> Object13 + __Value2["__Value[2∈0] ➊
ᐸcontextᐳ"]:::plan + __Value2 --> Access11 + __Value2 --> Access12 + Connection14[["Connection[14∈0] ➊
ᐸ10ᐳ"]]:::plan + PgSelect10 --> Connection14 + __InputObject7 --> ApplyInput15 + ConnectionItems17[["ConnectionItems[17∈0] ➊"]]:::plan + Connection14 --> ConnectionItems17 + __Item20[/"__Item[20∈3]
ᐸ17ᐳ"\]:::itemplan + ConnectionItems17 ==> __Item20 + PgSelectSingle21{{"PgSelectSingle[21∈3]
ᐸsingle_table_itemsᐳ"}}:::plan + __Item20 --> PgSelectSingle21 + PgClassExpression22{{"PgClassExpression[22∈3]
ᐸ__single_t...ems__.”id”ᐳ"}}:::plan + PgSelectSingle21 --> PgClassExpression22 + PgClassExpression25{{"PgClassExpression[25∈3]
ᐸ__single_t...s__.”type”ᐳ"}}:::plan + PgSelectSingle21 --> PgClassExpression25 + Lambda26{{"Lambda[26∈3]
ᐸSingleTableItem_typeNameFromTypeᐳ"}}:::plan + PgClassExpression25 --> Lambda26 + PgSelect39[["PgSelect[39∈4]^
ᐸsingle_table_items_topicsᐳ
More deps:
- Object[13]
- Constantᐸ2ᐳ[61]"]]:::plan + PgClassExpression38{{"PgClassExpression[38∈4]
ᐸ__single_table_items__ᐳ
ᐳSingleTablePost"}}:::plan + PgFromExpression43{{"PgFromExpression[43∈4] ➊
ᐳSingleTablePost"}}:::plan + PgClassExpression38 & PgFromExpression43 --> PgSelect39 + PgSelect45[["PgSelect[45∈4]^
ᐸsingle_table_items_topicsᐳ
More deps:
- Object[13]"]]:::plan + PgFromExpression47{{"PgFromExpression[47∈4] ➊
ᐳSingleTablePost"}}:::plan + PgClassExpression38 & PgFromExpression47 --> PgSelect45 + Connection44[["Connection[44∈4]^
ᐸ39ᐳ
More deps:
- Constantᐸ2ᐳ[61]"]]:::plan + PgSelect39 --> Connection44 + PgSelectSingle21 --> PgClassExpression38 + PgSelectRows48[["PgSelectRows[48∈4]^"]]:::plan + PgSelect45 --> PgSelectRows48 + ConnectionItems51[["ConnectionItems[51∈4]^"]]:::plan + Connection44 --> ConnectionItems51 + __Item49[/"__Item[49∈5]
ᐸ48ᐳ
ᐳSingleTablePost"\]:::itemplan + PgSelectRows48 ==> __Item49 + PgSelectSingle50{{"PgSelectSingle[50∈5]^
ᐸsingle_table_items_topicsᐳ"}}:::plan + __Item49 --> PgSelectSingle50 + PgClassExpression56{{"PgClassExpression[56∈6]
ᐸ__single_t...ics__.”id”ᐳ
ᐳSingleTablePost"}}:::plan + PgSelectSingle50 --> PgClassExpression56 + PgClassExpression57{{"PgClassExpression[57∈6]
ᐸ__single_t...__.”title”ᐳ
ᐳSingleTablePost"}}:::plan + PgClassExpression56 o--o PgClassExpression57 + __Item54[/"__Item[54∈8]
ᐸ51ᐳ
ᐳSingleTablePost"\]:::itemplan + ConnectionItems51 ==> __Item54 + PgSelectSingle55{{"PgSelectSingle[55∈8]^
ᐸsingle_table_items_topicsᐳ"}}:::plan + __Item54 --> PgSelectSingle55 + PgClassExpression58{{"PgClassExpression[58∈9]
ᐸ__single_t...ics__.”id”ᐳ
ᐳSingleTablePost"}}:::plan + PgSelectSingle55 --> PgClassExpression58 + PgClassExpression59{{"PgClassExpression[59∈9]
ᐸ__single_t...__.”title”ᐳ
ᐳSingleTablePost"}}:::plan + PgClassExpression58 o--o PgClassExpression59 + + %% define steps + classDef bucket0 stroke:#696969 + class Bucket0,__Value2,__InputObject7,PgSelect10,Access11,Access12,Object13,Connection14,ApplyInput15,ConnectionItems17 bucket0 + classDef bucket1 stroke:#00bfff + class Bucket1 bucket1 + classDef bucket3 stroke:#ffa500 + class Bucket3,__Item20,PgSelectSingle21,PgClassExpression22,PgClassExpression25,Lambda26 bucket3 + classDef bucket4 stroke:#0000ff + class Bucket4,PgClassExpression38,PgSelect39,PgFromExpression43,Connection44,PgSelect45,PgFromExpression47,PgSelectRows48,ConnectionItems51 bucket4 + classDef bucket5 stroke:#7fff00 + class Bucket5,__Item49,PgSelectSingle50 bucket5 + classDef bucket6 stroke:#ff1493 + class Bucket6,PgClassExpression56,PgClassExpression57 bucket6 + classDef bucket8 stroke:#dda0dd + class Bucket8,__Item54,PgSelectSingle55 bucket8 + classDef bucket9 stroke:#ff0000 + class Bucket9,PgClassExpression58,PgClassExpression59 bucket9 + diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.sql b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.sql new file mode 100644 index 0000000000..4f555c43ff --- /dev/null +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.sql @@ -0,0 +1,36 @@ +select + __single_table_items__."id"::text as "0", + __single_table_items__."type"::text as "1", + case when (__single_table_items__) is not distinct from null then null::text else json_build_array( + (((__single_table_items__)."id"))::text, + (((__single_table_items__)."type"))::text, + (((__single_table_items__)."parent_id"))::text, + (((__single_table_items__)."root_topic_id"))::text, + (((__single_table_items__)."author_id"))::text, + (((__single_table_items__)."position"))::text, + to_char(((__single_table_items__)."created_at"), 'YYYY-MM-DD"T"HH24:MI:SS.USTZH:TZM'::text), + to_char(((__single_table_items__)."updated_at"), 'YYYY-MM-DD"T"HH24:MI:SS.USTZH:TZM'::text), + (((__single_table_items__)."is_explicitly_archived"))::text, + to_char(((__single_table_items__)."archived_at"), 'YYYY-MM-DD"T"HH24:MI:SS.USTZH:TZM'::text), + ((__single_table_items__)."title"), + ((__single_table_items__)."description"), + ((__single_table_items__)."note"), + ((__single_table_items__)."color"), + (((__single_table_items__)."priority_id"))::text + )::text end as "2" +from "polymorphic"."single_table_items" as __single_table_items__ +where ( + __single_table_items__."id" = $1::"int4" +) +order by __single_table_items__."id" asc; + +select + __single_table_items_topics__."id"::text as "0", + __single_table_items_topics__."title" as "1" +from "polymorphic"."single_table_items_topics"($1::"polymorphic"."single_table_items") as __single_table_items_topics__ +limit 2; + +select + __single_table_items_topics__."id"::text as "0", + __single_table_items_topics__."title" as "1" +from "polymorphic"."single_table_items_topics"($1::"polymorphic"."single_table_items") as __single_table_items_topics__; \ No newline at end of file diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.test.graphql b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.test.graphql new file mode 100644 index 0000000000..a09d558b36 --- /dev/null +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.test.graphql @@ -0,0 +1,35 @@ +## expect(errors).toBeFalsy() +#> schema: ["polymorphic"] +#> simpleCollections: "both" + +{ + __type(name: "SingleTablePost") { + fields { + name + type { + name + ofType { + name + } + } + } + } + allSingleTableItems(condition: { id: 4 }) { + nodes { + id + type + ... on SingleTablePost { + topics(first: 2) { + nodes { + id + title + } + } + topicsList { + id + title + } + } + } + } +} diff --git a/postgraphile/postgraphile/__tests__/schema/v4/defaultOptions.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/defaultOptions.1.export.mjs index 1aabb0f777..c42bf086ad 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/defaultOptions.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/defaultOptions.1.export.mjs @@ -8995,7 +8995,7 @@ type Query implements Node { currentUserId: Int funcOut: Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcOutSetof( """Only read the first \`n\` values of the set.""" first: Int @@ -9041,7 +9041,7 @@ type Query implements Node { ): QueryIntervalSetConnection queryTextArray: [String] - """Reads and enables pagination through a set of \`Int8\`.""" + """Reads and enables pagination through a set of \`BigInt\`.""" staticBigInteger( """Only read the first \`n\` values of the set.""" first: Int @@ -9063,7 +9063,7 @@ type Query implements Node { ): StaticBigIntegerConnection funcInOut(i: Int): Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcReturnsTableOneCol( i: Int @@ -9137,7 +9137,7 @@ type Query implements Node { optionalMissingMiddle5(a: Int!, arg1: Int, arg2: Int): Int funcOutUnnamedOutOutUnnamed: FuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" intSetQuery( x: Int y: Int diff --git a/postgraphile/postgraphile/__tests__/schema/v4/defaultOptions.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/defaultOptions.1.graphql index 7b280865f9..f1be4b4090 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/defaultOptions.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/defaultOptions.1.graphql @@ -7563,7 +7563,7 @@ type Query implements Node { ): FuncOutOutSetofConnection funcOutOutUnnamed: FuncOutOutUnnamedRecord - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcOutSetof( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7635,7 +7635,7 @@ type Query implements Node { offset: Int ): FuncReturnsTableMultiColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcReturnsTableOneCol( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7666,7 +7666,7 @@ type Query implements Node { """Get a single `Input`.""" inputById(id: Int!): Input - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" intSetQuery( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7895,7 +7895,7 @@ type Query implements Node { """Get a single `SimilarTable2`.""" similarTable2ById(id: Int!): SimilarTable2 - """Reads and enables pagination through a set of `Int8`.""" + """Reads and enables pagination through a set of `BigInt`.""" staticBigInteger( """Read all values in the set after (below) this cursor.""" after: Cursor diff --git a/postgraphile/postgraphile/__tests__/schema/v4/defaultOptions.subscriptions.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/defaultOptions.subscriptions.1.export.mjs index 1aabb0f777..c42bf086ad 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/defaultOptions.subscriptions.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/defaultOptions.subscriptions.1.export.mjs @@ -8995,7 +8995,7 @@ type Query implements Node { currentUserId: Int funcOut: Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcOutSetof( """Only read the first \`n\` values of the set.""" first: Int @@ -9041,7 +9041,7 @@ type Query implements Node { ): QueryIntervalSetConnection queryTextArray: [String] - """Reads and enables pagination through a set of \`Int8\`.""" + """Reads and enables pagination through a set of \`BigInt\`.""" staticBigInteger( """Only read the first \`n\` values of the set.""" first: Int @@ -9063,7 +9063,7 @@ type Query implements Node { ): StaticBigIntegerConnection funcInOut(i: Int): Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcReturnsTableOneCol( i: Int @@ -9137,7 +9137,7 @@ type Query implements Node { optionalMissingMiddle5(a: Int!, arg1: Int, arg2: Int): Int funcOutUnnamedOutOutUnnamed: FuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" intSetQuery( x: Int y: Int diff --git a/postgraphile/postgraphile/__tests__/schema/v4/defaultOptions.subscriptions.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/defaultOptions.subscriptions.1.graphql index 7b280865f9..f1be4b4090 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/defaultOptions.subscriptions.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/defaultOptions.subscriptions.1.graphql @@ -7563,7 +7563,7 @@ type Query implements Node { ): FuncOutOutSetofConnection funcOutOutUnnamed: FuncOutOutUnnamedRecord - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcOutSetof( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7635,7 +7635,7 @@ type Query implements Node { offset: Int ): FuncReturnsTableMultiColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcReturnsTableOneCol( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7666,7 +7666,7 @@ type Query implements Node { """Get a single `Input`.""" inputById(id: Int!): Input - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" intSetQuery( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7895,7 +7895,7 @@ type Query implements Node { """Get a single `SimilarTable2`.""" similarTable2ById(id: Int!): SimilarTable2 - """Reads and enables pagination through a set of `Int8`.""" + """Reads and enables pagination through a set of `BigInt`.""" staticBigInteger( """Read all values in the set after (below) this cursor.""" after: Cursor diff --git a/postgraphile/postgraphile/__tests__/schema/v4/foreignKey-smart-tag-autofix.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/foreignKey-smart-tag-autofix.1.export.mjs index 4a3e1b8e5c..2ecb6ec49c 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/foreignKey-smart-tag-autofix.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/foreignKey-smart-tag-autofix.1.export.mjs @@ -5396,7 +5396,7 @@ type Query implements Node { currentUserId: Int funcOut: Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcOutSetof( """Only read the first \`n\` values of the set.""" first: Int @@ -5420,7 +5420,7 @@ type Query implements Node { noArgsQuery: Int funcInOut(i: Int): Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcReturnsTableOneCol( i: Int @@ -5470,7 +5470,7 @@ type Query implements Node { funcOutOutUnnamed: FuncOutOutUnnamedRecord funcOutUnnamedOutOutUnnamed: FuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" intSetQuery( x: Int y: Int diff --git a/postgraphile/postgraphile/__tests__/schema/v4/foreignKey-smart-tag-autofix.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/foreignKey-smart-tag-autofix.1.graphql index e9dfb81aea..7c37346143 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/foreignKey-smart-tag-autofix.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/foreignKey-smart-tag-autofix.1.graphql @@ -3676,7 +3676,7 @@ type Query implements Node { ): FuncOutOutSetofConnection funcOutOutUnnamed: FuncOutOutUnnamedRecord - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcOutSetof( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -3748,7 +3748,7 @@ type Query implements Node { offset: Int ): FuncReturnsTableMultiColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcReturnsTableOneCol( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -3770,7 +3770,7 @@ type Query implements Node { offset: Int ): FuncReturnsTableOneColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" intSetQuery( """Read all values in the set after (below) this cursor.""" after: Cursor diff --git a/postgraphile/postgraphile/__tests__/schema/v4/foreignKey-smart-tag-good.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/foreignKey-smart-tag-good.1.export.mjs index 60a2bb0fb0..758a4ca8eb 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/foreignKey-smart-tag-good.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/foreignKey-smart-tag-good.1.export.mjs @@ -5393,7 +5393,7 @@ type Query implements Node { currentUserId: Int funcOut: Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcOutSetof( """Only read the first \`n\` values of the set.""" first: Int @@ -5417,7 +5417,7 @@ type Query implements Node { noArgsQuery: Int funcInOut(i: Int): Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcReturnsTableOneCol( i: Int @@ -5467,7 +5467,7 @@ type Query implements Node { funcOutOutUnnamed: FuncOutOutUnnamedRecord funcOutUnnamedOutOutUnnamed: FuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" intSetQuery( x: Int y: Int diff --git a/postgraphile/postgraphile/__tests__/schema/v4/foreignKey-smart-tag-good.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/foreignKey-smart-tag-good.1.graphql index a069cc165c..c7c515d3ec 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/foreignKey-smart-tag-good.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/foreignKey-smart-tag-good.1.graphql @@ -3703,7 +3703,7 @@ type Query implements Node { ): FuncOutOutSetofConnection funcOutOutUnnamed: FuncOutOutUnnamedRecord - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcOutSetof( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -3775,7 +3775,7 @@ type Query implements Node { offset: Int ): FuncReturnsTableMultiColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcReturnsTableOneCol( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -3797,7 +3797,7 @@ type Query implements Node { offset: Int ): FuncReturnsTableOneColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" intSetQuery( """Read all values in the set after (below) this cursor.""" after: Cursor diff --git a/postgraphile/postgraphile/__tests__/schema/v4/function-clash-with-tags-file-workaround.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/function-clash-with-tags-file-workaround.1.export.mjs index e1ad4653c6..c704be06f8 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/function-clash-with-tags-file-workaround.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/function-clash-with-tags-file-workaround.1.export.mjs @@ -9033,7 +9033,7 @@ type Query implements Node { currentUserId: Int funcOut: Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcOutSetof( """Only read the first \`n\` values of the set.""" first: Int @@ -9079,7 +9079,7 @@ type Query implements Node { ): QueryIntervalSetConnection queryTextArray: [String] - """Reads and enables pagination through a set of \`Int8\`.""" + """Reads and enables pagination through a set of \`BigInt\`.""" staticBigInteger( """Only read the first \`n\` values of the set.""" first: Int @@ -9101,7 +9101,7 @@ type Query implements Node { ): StaticBigIntegerConnection funcInOut(i: Int): Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcReturnsTableOneCol( i: Int @@ -9175,7 +9175,7 @@ type Query implements Node { optionalMissingMiddle5(a: Int!, arg1: Int, arg2: Int): Int funcOutUnnamedOutOutUnnamed: FuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" intSetQuery( x: Int y: Int diff --git a/postgraphile/postgraphile/__tests__/schema/v4/function-clash-with-tags-file-workaround.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/function-clash-with-tags-file-workaround.1.graphql index 96da061aaa..27a214b67d 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/function-clash-with-tags-file-workaround.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/function-clash-with-tags-file-workaround.1.graphql @@ -7557,7 +7557,7 @@ type Query implements Node { ): FuncOutOutSetofConnection funcOutOutUnnamed: FuncOutOutUnnamedRecord - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcOutSetof( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7629,7 +7629,7 @@ type Query implements Node { offset: Int ): FuncReturnsTableMultiColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcReturnsTableOneCol( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7660,7 +7660,7 @@ type Query implements Node { """Get a single `Input`.""" inputById(id: Int!): Input - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" intSetQuery( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7889,7 +7889,7 @@ type Query implements Node { """Get a single `SimilarTable2`.""" similarTable2ById(id: Int!): SimilarTable2 - """Reads and enables pagination through a set of `Int8`.""" + """Reads and enables pagination through a set of `BigInt`.""" staticBigInteger( """Read all values in the set after (below) this cursor.""" after: Cursor diff --git a/postgraphile/postgraphile/__tests__/schema/v4/function-clash.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/function-clash.1.export.mjs index c05880c85c..307c405c03 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/function-clash.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/function-clash.1.export.mjs @@ -9017,7 +9017,7 @@ type Query implements Node { currentUserId: Int funcOut: Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcOutSetof( """Only read the first \`n\` values of the set.""" first: Int @@ -9063,7 +9063,7 @@ type Query implements Node { ): QueryIntervalSetConnection queryTextArray: [String] - """Reads and enables pagination through a set of \`Int8\`.""" + """Reads and enables pagination through a set of \`BigInt\`.""" staticBigInteger( """Only read the first \`n\` values of the set.""" first: Int @@ -9085,7 +9085,7 @@ type Query implements Node { ): StaticBigIntegerConnection funcInOut(i: Int): Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcReturnsTableOneCol( i: Int @@ -9159,7 +9159,7 @@ type Query implements Node { optionalMissingMiddle5(a: Int!, arg1: Int, arg2: Int): Int funcOutUnnamedOutOutUnnamed: FuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" intSetQuery( x: Int y: Int diff --git a/postgraphile/postgraphile/__tests__/schema/v4/function-clash.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/function-clash.1.graphql index 7b280865f9..f1be4b4090 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/function-clash.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/function-clash.1.graphql @@ -7563,7 +7563,7 @@ type Query implements Node { ): FuncOutOutSetofConnection funcOutOutUnnamed: FuncOutOutUnnamedRecord - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcOutSetof( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7635,7 +7635,7 @@ type Query implements Node { offset: Int ): FuncReturnsTableMultiColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcReturnsTableOneCol( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7666,7 +7666,7 @@ type Query implements Node { """Get a single `Input`.""" inputById(id: Int!): Input - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" intSetQuery( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7895,7 +7895,7 @@ type Query implements Node { """Get a single `SimilarTable2`.""" similarTable2ById(id: Int!): SimilarTable2 - """Reads and enables pagination through a set of `Int8`.""" + """Reads and enables pagination through a set of `BigInt`.""" staticBigInteger( """Read all values in the set after (below) this cursor.""" after: Cursor diff --git a/postgraphile/postgraphile/__tests__/schema/v4/indexes.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/indexes.1.export.mjs index 6b637dc6db..b1e4003714 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/indexes.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/indexes.1.export.mjs @@ -9522,7 +9522,7 @@ type Query implements Node { currentUserId: Int funcOut: Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcOutSetof( """Only read the first \`n\` values of the set.""" first: Int @@ -9568,7 +9568,7 @@ type Query implements Node { ): QueryIntervalSetConnection queryTextArray: [String] - """Reads and enables pagination through a set of \`Int8\`.""" + """Reads and enables pagination through a set of \`BigInt\`.""" staticBigInteger( """Only read the first \`n\` values of the set.""" first: Int @@ -9590,7 +9590,7 @@ type Query implements Node { ): StaticBigIntegerConnection funcInOut(i: Int): Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcReturnsTableOneCol( i: Int @@ -9664,7 +9664,7 @@ type Query implements Node { optionalMissingMiddle5(a: Int!, arg1: Int, arg2: Int): Int funcOutUnnamedOutOutUnnamed: FuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" intSetQuery( x: Int y: Int diff --git a/postgraphile/postgraphile/__tests__/schema/v4/indexes.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/indexes.1.graphql index 1ac995ecd4..849421628d 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/indexes.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/indexes.1.graphql @@ -7309,7 +7309,7 @@ type Query implements Node { ): FuncOutOutSetofConnection funcOutOutUnnamed: FuncOutOutUnnamedRecord - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcOutSetof( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7381,7 +7381,7 @@ type Query implements Node { offset: Int ): FuncReturnsTableMultiColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcReturnsTableOneCol( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7412,7 +7412,7 @@ type Query implements Node { """Get a single `Input`.""" inputById(id: Int!): Input - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" intSetQuery( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7641,7 +7641,7 @@ type Query implements Node { """Get a single `SimilarTable2`.""" similarTable2ById(id: Int!): SimilarTable2 - """Reads and enables pagination through a set of `Int8`.""" + """Reads and enables pagination through a set of `BigInt`.""" staticBigInteger( """Read all values in the set after (below) this cursor.""" after: Cursor diff --git a/postgraphile/postgraphile/__tests__/schema/v4/inflect-builtin-lowercase.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/inflect-builtin-lowercase.1.export.mjs index e14ec4dc03..8f20fa6c77 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/inflect-builtin-lowercase.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/inflect-builtin-lowercase.1.export.mjs @@ -9000,7 +9000,7 @@ type query implements node { currentUserId: Int funcOut: Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcOutSetof( """Only read the first \`n\` values of the set.""" first: Int @@ -9024,7 +9024,7 @@ type query implements node { noArgsQuery: Int queryIntervalArray: [interval] - """Reads and enables pagination through a set of \`Interval\`.""" + """Reads and enables pagination through a set of \`interval\`.""" queryIntervalSet( """Only read the first \`n\` values of the set.""" first: Int @@ -9046,7 +9046,7 @@ type query implements node { ): QueryIntervalSetConnection queryTextArray: [String] - """Reads and enables pagination through a set of \`Int8\`.""" + """Reads and enables pagination through a set of \`bigint\`.""" staticBigInteger( """Only read the first \`n\` values of the set.""" first: Int @@ -9068,7 +9068,7 @@ type query implements node { ): StaticBigIntegerConnection funcInOut(i: Int): Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcReturnsTableOneCol( i: Int @@ -9142,7 +9142,7 @@ type query implements node { optionalMissingMiddle5(a: Int!, arg1: Int, arg2: Int): Int funcOutUnnamedOutOutUnnamed: FuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" intSetQuery( x: Int y: Int @@ -10658,7 +10658,7 @@ type Post implements node { nodeId: ID! computedIntervalArray: [interval] - """Reads and enables pagination through a set of \`Interval\`.""" + """Reads and enables pagination through a set of \`interval\`.""" computedIntervalSet( """Only read the first \`n\` values of the set.""" first: Int diff --git a/postgraphile/postgraphile/__tests__/schema/v4/inflect-builtin-lowercase.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/inflect-builtin-lowercase.1.graphql index 920decf6e7..28847f8418 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/inflect-builtin-lowercase.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/inflect-builtin-lowercase.1.graphql @@ -5023,7 +5023,7 @@ type Post implements node { computedCompoundTypeArray(object: CompoundTypeInput): [CompoundType] computedIntervalArray: [interval] - """Reads and enables pagination through a set of `Interval`.""" + """Reads and enables pagination through a set of `interval`.""" computedIntervalSet( """Read all values in the set after (below) this cursor.""" after: cursor @@ -10053,7 +10053,7 @@ type query implements node { ): FuncOutOutSetofConnection funcOutOutUnnamed: FuncOutOutUnnamedRecord - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcOutSetof( """Read all values in the set after (below) this cursor.""" after: cursor @@ -10125,7 +10125,7 @@ type query implements node { offset: Int ): FuncReturnsTableMultiColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcReturnsTableOneCol( """Read all values in the set after (below) this cursor.""" after: cursor @@ -10156,7 +10156,7 @@ type query implements node { """Get a single `Input`.""" inputById(id: Int!): Input - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" intSetQuery( """Read all values in the set after (below) this cursor.""" after: cursor @@ -10301,7 +10301,7 @@ type query implements node { queryCompoundTypeArray(object: CompoundTypeInput): [CompoundType] queryIntervalArray: [interval] - """Reads and enables pagination through a set of `Interval`.""" + """Reads and enables pagination through a set of `interval`.""" queryIntervalSet( """Read all values in the set after (below) this cursor.""" after: cursor @@ -10385,7 +10385,7 @@ type query implements node { """Get a single `SimilarTable2`.""" similarTable2ById(id: Int!): SimilarTable2 - """Reads and enables pagination through a set of `Int8`.""" + """Reads and enables pagination through a set of `bigint`.""" staticBigInteger( """Read all values in the set after (below) this cursor.""" after: cursor diff --git a/postgraphile/postgraphile/__tests__/schema/v4/inflect-core.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/inflect-core.1.export.mjs index a4d0ea7530..f2d3f73ce0 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/inflect-core.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/inflect-core.1.export.mjs @@ -9000,7 +9000,7 @@ type Q implements N { currentUserId: Int funcOut: Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcOutSetof( """Only read the first \`n\` values of the set.""" first: Int @@ -9024,7 +9024,7 @@ type Q implements N { noArgsQuery: Int queryIntervalArray: [I] - """Reads and enables pagination through a set of \`Interval\`.""" + """Reads and enables pagination through a set of \`I\`.""" queryIntervalSet( """Only read the first \`n\` values of the set.""" first: Int @@ -9046,7 +9046,7 @@ type Q implements N { ): QueryIntervalSetConnection queryTextArray: [String] - """Reads and enables pagination through a set of \`Int8\`.""" + """Reads and enables pagination through a set of \`BigInt\`.""" staticBigInteger( """Only read the first \`n\` values of the set.""" first: Int @@ -9068,7 +9068,7 @@ type Q implements N { ): StaticBigIntegerConnection funcInOut(i: Int): Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcReturnsTableOneCol( i: Int @@ -9142,7 +9142,7 @@ type Q implements N { optionalMissingMiddle5(a: Int!, arg1: Int, arg2: Int): Int funcOutUnnamedOutOutUnnamed: FuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" intSetQuery( x: Int y: Int @@ -10658,7 +10658,7 @@ type Post implements N { nodeId: ID! computedIntervalArray: [I] - """Reads and enables pagination through a set of \`Interval\`.""" + """Reads and enables pagination through a set of \`I\`.""" computedIntervalSet( """Only read the first \`n\` values of the set.""" first: Int diff --git a/postgraphile/postgraphile/__tests__/schema/v4/inflect-core.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/inflect-core.1.graphql index 4f489e070b..4e31135dee 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/inflect-core.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/inflect-core.1.graphql @@ -6462,7 +6462,7 @@ type Post implements N { computedCompoundTypeArray(object: CompoundTypeInput): [CompoundType] computedIntervalArray: [I] - """Reads and enables pagination through a set of `Interval`.""" + """Reads and enables pagination through a set of `I`.""" computedIntervalSet( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7568,7 +7568,7 @@ type Q implements N { ): FuncOutOutSetofConnection funcOutOutUnnamed: FuncOutOutUnnamedRecord - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcOutSetof( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7640,7 +7640,7 @@ type Q implements N { offset: Int ): FuncReturnsTableMultiColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcReturnsTableOneCol( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7671,7 +7671,7 @@ type Q implements N { """Get a single `Input`.""" inputById(id: Int!): Input - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" intSetQuery( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7816,7 +7816,7 @@ type Q implements N { queryCompoundTypeArray(object: CompoundTypeInput): [CompoundType] queryIntervalArray: [I] - """Reads and enables pagination through a set of `Interval`.""" + """Reads and enables pagination through a set of `I`.""" queryIntervalSet( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7900,7 +7900,7 @@ type Q implements N { """Get a single `SimilarTable2`.""" similarTable2ById(id: Int!): SimilarTable2 - """Reads and enables pagination through a set of `Int8`.""" + """Reads and enables pagination through a set of `BigInt`.""" staticBigInteger( """Read all values in the set after (below) this cursor.""" after: Cursor diff --git a/postgraphile/postgraphile/__tests__/schema/v4/noDefaultMutations.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/noDefaultMutations.1.export.mjs index 1b5ecbcdd2..26b1923bf8 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/noDefaultMutations.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/noDefaultMutations.1.export.mjs @@ -5234,7 +5234,7 @@ type Query implements Node { currentUserId: Int funcOut: Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcOutSetof( """Only read the first \`n\` values of the set.""" first: Int @@ -5258,7 +5258,7 @@ type Query implements Node { noArgsQuery: Int funcInOut(i: Int): Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcReturnsTableOneCol( i: Int @@ -5308,7 +5308,7 @@ type Query implements Node { funcOutOutUnnamed: FuncOutOutUnnamedRecord funcOutUnnamedOutOutUnnamed: FuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" intSetQuery( x: Int y: Int diff --git a/postgraphile/postgraphile/__tests__/schema/v4/noDefaultMutations.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/noDefaultMutations.1.graphql index 6a9479652e..931205cd7d 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/noDefaultMutations.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/noDefaultMutations.1.graphql @@ -2511,7 +2511,7 @@ type Query implements Node { ): FuncOutOutSetofConnection funcOutOutUnnamed: FuncOutOutUnnamedRecord - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcOutSetof( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -2583,7 +2583,7 @@ type Query implements Node { offset: Int ): FuncReturnsTableMultiColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcReturnsTableOneCol( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -2605,7 +2605,7 @@ type Query implements Node { offset: Int ): FuncReturnsTableOneColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" intSetQuery( """Read all values in the set after (below) this cursor.""" after: Cursor diff --git a/postgraphile/postgraphile/__tests__/schema/v4/pgStrictFunctions.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/pgStrictFunctions.1.export.mjs index 0a4fabc257..106374736f 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/pgStrictFunctions.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/pgStrictFunctions.1.export.mjs @@ -9101,7 +9101,7 @@ type Query implements Node { currentUserId: Int funcOut: Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcOutSetof( """Only read the first \`n\` values of the set.""" first: Int @@ -9147,7 +9147,7 @@ type Query implements Node { ): QueryIntervalSetConnection queryTextArray: [String] - """Reads and enables pagination through a set of \`Int8\`.""" + """Reads and enables pagination through a set of \`BigInt\`.""" staticBigInteger( """Only read the first \`n\` values of the set.""" first: Int @@ -9169,7 +9169,7 @@ type Query implements Node { ): StaticBigIntegerConnection funcInOut(i: Int!): Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcReturnsTableOneCol( i: Int! @@ -9243,7 +9243,7 @@ type Query implements Node { optionalMissingMiddle5(a: Int!, arg1: Int, arg2: Int): Int funcOutUnnamedOutOutUnnamed: FuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" intSetQuery( x: Int! y: Int! diff --git a/postgraphile/postgraphile/__tests__/schema/v4/pgStrictFunctions.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/pgStrictFunctions.1.graphql index 2ae0a818d5..e401f7a9a6 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/pgStrictFunctions.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/pgStrictFunctions.1.graphql @@ -7563,7 +7563,7 @@ type Query implements Node { ): FuncOutOutSetofConnection funcOutOutUnnamed: FuncOutOutUnnamedRecord - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcOutSetof( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7635,7 +7635,7 @@ type Query implements Node { offset: Int ): FuncReturnsTableMultiColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcReturnsTableOneCol( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7666,7 +7666,7 @@ type Query implements Node { """Get a single `Input`.""" inputById(id: Int!): Input - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" intSetQuery( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7895,7 +7895,7 @@ type Query implements Node { """Get a single `SimilarTable2`.""" similarTable2ById(id: Int!): SimilarTable2 - """Reads and enables pagination through a set of `Int8`.""" + """Reads and enables pagination through a set of `BigInt`.""" staticBigInteger( """Read all values in the set after (below) this cursor.""" after: Cursor diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs index 9a8c3eb21e..a7ee0453a2 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs @@ -2703,6 +2703,7 @@ const single_table_items_resourceOptionsConfig = { }; const all_single_tablesFunctionIdentifer = sql.identifier("polymorphic", "all_single_tables"); const get_single_table_topic_by_idFunctionIdentifer = sql.identifier("polymorphic", "get_single_table_topic_by_id"); +const single_table_items_topicsFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_topics"); const relational_itemsUniques = [{ attributes: ["id"], isPrimary: true @@ -3331,6 +3332,29 @@ const registryConfig = { } } }), + single_table_items_topics: PgResource.functionResourceOptions(single_table_items_resourceOptionsConfig, { + name: "single_table_items_topics", + identifier: "main.polymorphic.single_table_items_topics(polymorphic.single_table_items)", + from(...args) { + return sql`${single_table_items_topicsFunctionIdentifer}(${sqlFromArgDigests(args)})`; + }, + parameters: [{ + name: "sti", + codec: singleTableItemsCodec + }], + returnsSetof: true, + extensions: { + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "single_table_items_topics" + }, + tags: { + returnType: "SingleTableTopic" + } + }, + hasImplicitOrder: true + }), relational_items: relational_items_resourceOptionsConfig, all_relational_items_fn: PgResource.functionResourceOptions(relational_items_resourceOptionsConfig, { name: "all_relational_items_fn", @@ -4033,6 +4057,30 @@ const scalarComputed = (resource, $in, args) => { const single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs = ($in, args, _info) => { return scalarComputed(resource_single_table_items_meaning_of_lifePgResource, $in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); }; +const resource_single_table_items_topicsPgResource = registry.pgResources["single_table_items_topics"]; +const single_table_items_topics_getSelectPlanFromParentAndArgs = ($in, args, _info) => { + const details = pgFunctionArgumentsFromArgs($in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); + return resource_single_table_items_topicsPgResource.execute(details.selectArgs); +}; +function SingleTableTopic_topicsPlan($parent, args, info) { + const $select = single_table_items_topics_getSelectPlanFromParentAndArgs($parent, args, info); + return connection($select); +} +function applyFirstArg(_, $connection, arg) { + $connection.setFirst(arg.getRaw()); +} +function applyLastArg(_, $connection, val) { + $connection.setLast(val.getRaw()); +} +function applyOffsetArg(_, $connection, val) { + $connection.setOffset(val.getRaw()); +} +function applyBeforeArg(_, $connection, val) { + $connection.setBefore(val.getRaw()); +} +function applyAfterArg(_, $connection, val) { + $connection.setAfter(val.getRaw()); +} const SingleTableTopic_parentIdPlan = $record => { return $record.get("parent_id"); }; @@ -4068,21 +4116,6 @@ const SingleTableTopic_singleTableItemsByParentIdPlan = $record => { }); return connection($records); }; -function applyFirstArg(_, $connection, arg) { - $connection.setFirst(arg.getRaw()); -} -function applyLastArg(_, $connection, val) { - $connection.setLast(val.getRaw()); -} -function applyOffsetArg(_, $connection, val) { - $connection.setOffset(val.getRaw()); -} -function applyBeforeArg(_, $connection, val) { - $connection.setBefore(val.getRaw()); -} -function applyAfterArg(_, $connection, val) { - $connection.setAfter(val.getRaw()); -} function qbWhereBuilder(qb) { return qb.whereBuilder(); } @@ -5491,6 +5524,27 @@ const resourceByTypeName17 = { }; export const typeDefs = /* GraphQL */`type SingleTableTopic implements SingleTableItem { meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! id: Int! type: ItemType! parentId: Int @@ -6760,6 +6814,34 @@ type SingleTableItemRelationCompositePksEdge { node: SingleTableItemRelationCompositePk } +"""A connection to a list of \`SingleTableTopic\` values.""" +type SingleTableTopicConnection { + """A list of \`SingleTableTopic\` objects.""" + nodes: [SingleTableTopic]! + + """ + A list of edges which contains the \`SingleTableTopic\` and cursor to aid in pagination. + """ + edges: [SingleTableTopicEdge]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* \`SingleTableItem\` you could get from the connection. + """ + totalCount: Int! +} + +"""A \`SingleTableTopic\` edge in the connection.""" +type SingleTableTopicEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The \`SingleTableTopic\` at the end of the edge.""" + node: SingleTableTopic +} + """ A condition to be used against \`SingleTableItemRelation\` object types. All fields are tested for equality and combined with a logical ‘and.’ @@ -6813,6 +6895,27 @@ enum SingleTableItemRelationCompositePksOrderBy { type SingleTablePost implements SingleTableItem { meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! id: Int! type: ItemType! parentId: Int @@ -7034,6 +7137,27 @@ type Priority { type SingleTableDivider implements SingleTableItem { meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! id: Int! type: ItemType! parentId: Int @@ -7216,6 +7340,27 @@ type SingleTableDivider implements SingleTableItem { type SingleTableChecklist implements SingleTableItem { meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! id: Int! type: ItemType! parentId: Int @@ -7402,6 +7547,27 @@ type SingleTableChecklist implements SingleTableItem { type SingleTableChecklistItem implements SingleTableItem { meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! id: Int! type: ItemType! parentId: Int @@ -13256,6 +13422,16 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, @@ -13334,6 +13510,16 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, @@ -13410,6 +13596,16 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, @@ -13541,6 +13737,16 @@ export const objects = { subject($record) { return $record.get("title"); }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, @@ -13617,9 +13823,25 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, + SingleTableTopicConnection: { + assertStep: ConnectionStep, + plans: { + totalCount: totalCountConnectionPlan + } + }, ThirdPartyVulnerability: { assertStep: assertPgClassSingleStep, plans: { diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql index c6d49921db..2204639388 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql @@ -4238,6 +4238,27 @@ type SingleTableChecklist implements SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! title: String + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } @@ -4424,6 +4445,27 @@ type SingleTableChecklistItem implements SingleTableItem { """The method to use when ordering `SingleTableItem`.""" orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } @@ -4606,6 +4648,27 @@ type SingleTableDivider implements SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! title: String + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } @@ -5161,6 +5224,27 @@ type SingleTablePost implements SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! subject: String + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } @@ -5342,10 +5426,59 @@ type SingleTableTopic implements SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! title: String! + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } +"""A connection to a list of `SingleTableTopic` values.""" +type SingleTableTopicConnection { + """ + A list of edges which contains the `SingleTableTopic` and cursor to aid in pagination. + """ + edges: [SingleTableTopicEdge]! + + """A list of `SingleTableTopic` objects.""" + nodes: [SingleTableTopic]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* `SingleTableItem` you could get from the connection. + """ + totalCount: Int! +} + +"""A `SingleTableTopic` edge in the connection.""" +type SingleTableTopicEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The `SingleTableTopic` at the end of the edge.""" + node: SingleTableTopic +} + type ThirdPartyVulnerability implements Vulnerability { """Reads and enables pagination through a set of `Application`.""" applications( diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs index 4b0403f134..a7792f2a3f 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs @@ -2716,6 +2716,7 @@ const single_table_items_resourceOptionsConfig = { }; const all_single_tablesFunctionIdentifer = sql.identifier("polymorphic", "all_single_tables"); const get_single_table_topic_by_idFunctionIdentifer = sql.identifier("polymorphic", "get_single_table_topic_by_id"); +const single_table_items_topicsFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_topics"); const relational_itemsUniques = [{ attributes: ["id"], isPrimary: true @@ -3344,6 +3345,29 @@ const registryConfig = { } } }), + single_table_items_topics: PgResource.functionResourceOptions(single_table_items_resourceOptionsConfig, { + name: "single_table_items_topics", + identifier: "main.polymorphic.single_table_items_topics(polymorphic.single_table_items)", + from(...args) { + return sql`${single_table_items_topicsFunctionIdentifer}(${sqlFromArgDigests(args)})`; + }, + parameters: [{ + name: "sti", + codec: singleTableItemsCodec + }], + returnsSetof: true, + extensions: { + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "single_table_items_topics" + }, + tags: { + returnType: "SingleTableTopic" + } + }, + hasImplicitOrder: true + }), relational_items: relational_items_resourceOptionsConfig, all_relational_items_fn: PgResource.functionResourceOptions(relational_items_resourceOptionsConfig, { name: "all_relational_items_fn", @@ -4086,6 +4110,30 @@ const scalarComputed = (resource, $in, args) => { const single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs = ($in, args, _info) => { return scalarComputed(resource_single_table_items_meaning_of_lifePgResource, $in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); }; +const resource_single_table_items_topicsPgResource = registry.pgResources["single_table_items_topics"]; +const single_table_items_topics_getSelectPlanFromParentAndArgs = ($in, args, _info) => { + const details = pgFunctionArgumentsFromArgs($in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); + return resource_single_table_items_topicsPgResource.execute(details.selectArgs); +}; +function SingleTableTopic_topicsPlan($parent, args, info) { + const $select = single_table_items_topics_getSelectPlanFromParentAndArgs($parent, args, info); + return connection($select); +} +function applyFirstArg(_, $connection, arg) { + $connection.setFirst(arg.getRaw()); +} +function applyLastArg(_, $connection, val) { + $connection.setLast(val.getRaw()); +} +function applyOffsetArg(_, $connection, val) { + $connection.setOffset(val.getRaw()); +} +function applyBeforeArg(_, $connection, val) { + $connection.setBefore(val.getRaw()); +} +function applyAfterArg(_, $connection, val) { + $connection.setAfter(val.getRaw()); +} const SingleTableTopic_parentIdPlan = $record => { return $record.get("parent_id"); }; @@ -4120,21 +4168,6 @@ const SingleTableTopic_singleTableItemsByParentIdPlan = $record => { }); return connection($records); }; -function applyFirstArg(_, $connection, arg) { - $connection.setFirst(arg.getRaw()); -} -function applyLastArg(_, $connection, val) { - $connection.setLast(val.getRaw()); -} -function applyOffsetArg(_, $connection, val) { - $connection.setOffset(val.getRaw()); -} -function applyBeforeArg(_, $connection, val) { - $connection.setBefore(val.getRaw()); -} -function applyAfterArg(_, $connection, val) { - $connection.setAfter(val.getRaw()); -} function qbWhereBuilder(qb) { return qb.whereBuilder(); } @@ -6218,6 +6251,27 @@ export const typeDefs = /* GraphQL */`type SingleTableTopic implements SingleTab """ nodeId: ID! meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! id: Int! type: ItemType! parentId: Int @@ -7935,6 +7989,34 @@ type SingleTableItemRelationCompositePksEdge { node: SingleTableItemRelationCompositePk } +"""A connection to a list of \`SingleTableTopic\` values.""" +type SingleTableTopicConnection { + """A list of \`SingleTableTopic\` objects.""" + nodes: [SingleTableTopic]! + + """ + A list of edges which contains the \`SingleTableTopic\` and cursor to aid in pagination. + """ + edges: [SingleTableTopicEdge]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* \`SingleTableItem\` you could get from the connection. + """ + totalCount: Int! +} + +"""A \`SingleTableTopic\` edge in the connection.""" +type SingleTableTopicEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The \`SingleTableTopic\` at the end of the edge.""" + node: SingleTableTopic +} + """ A condition to be used against \`SingleTableItemRelation\` object types. All fields are tested for equality and combined with a logical ‘and.’ @@ -7992,6 +8074,27 @@ type SingleTablePost implements SingleTableItem & Node { """ nodeId: ID! meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! id: Int! type: ItemType! parentId: Int @@ -8221,6 +8324,27 @@ type SingleTableDivider implements SingleTableItem & Node { """ nodeId: ID! meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! id: Int! type: ItemType! parentId: Int @@ -8407,6 +8531,27 @@ type SingleTableChecklist implements SingleTableItem & Node { """ nodeId: ID! meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! id: Int! type: ItemType! parentId: Int @@ -8597,6 +8742,27 @@ type SingleTableChecklistItem implements SingleTableItem & Node { """ nodeId: ID! meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! id: Int! type: ItemType! parentId: Int @@ -18970,6 +19136,16 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, @@ -19052,6 +19228,16 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, @@ -19132,6 +19318,16 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, @@ -19275,6 +19471,16 @@ export const objects = { subject($record) { return $record.get("title"); }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, @@ -19355,9 +19561,25 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, + SingleTableTopicConnection: { + assertStep: ConnectionStep, + plans: { + totalCount: totalCountConnectionPlan + } + }, ThirdPartyVulnerabilitiesConnection: { assertStep: ConnectionStep, plans: { diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql index 758a59aa0a..22ed5d8894 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql @@ -6854,6 +6854,27 @@ type SingleTableChecklist implements Node & SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! title: String + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } @@ -7045,6 +7066,27 @@ type SingleTableChecklistItem implements Node & SingleTableItem { """The method to use when ordering `SingleTableItem`.""" orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } @@ -7232,6 +7274,27 @@ type SingleTableDivider implements Node & SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! title: String + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } @@ -7837,6 +7900,27 @@ type SingleTablePost implements Node & SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! subject: String + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } @@ -8023,10 +8107,59 @@ type SingleTableTopic implements Node & SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! title: String! + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } +"""A connection to a list of `SingleTableTopic` values.""" +type SingleTableTopicConnection { + """ + A list of edges which contains the `SingleTableTopic` and cursor to aid in pagination. + """ + edges: [SingleTableTopicEdge]! + + """A list of `SingleTableTopic` objects.""" + nodes: [SingleTableTopic]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* `SingleTableItem` you could get from the connection. + """ + totalCount: Int! +} + +"""A `SingleTableTopic` edge in the connection.""" +type SingleTableTopicEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The `SingleTableTopic` at the end of the edge.""" + node: SingleTableTopic +} + """A connection to a list of `ThirdPartyVulnerability` values.""" type ThirdPartyVulnerabilitiesConnection { """ diff --git a/postgraphile/postgraphile/__tests__/schema/v4/rbac.ignore.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/rbac.ignore.1.export.mjs index 1aabb0f777..c42bf086ad 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/rbac.ignore.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/rbac.ignore.1.export.mjs @@ -8995,7 +8995,7 @@ type Query implements Node { currentUserId: Int funcOut: Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcOutSetof( """Only read the first \`n\` values of the set.""" first: Int @@ -9041,7 +9041,7 @@ type Query implements Node { ): QueryIntervalSetConnection queryTextArray: [String] - """Reads and enables pagination through a set of \`Int8\`.""" + """Reads and enables pagination through a set of \`BigInt\`.""" staticBigInteger( """Only read the first \`n\` values of the set.""" first: Int @@ -9063,7 +9063,7 @@ type Query implements Node { ): StaticBigIntegerConnection funcInOut(i: Int): Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcReturnsTableOneCol( i: Int @@ -9137,7 +9137,7 @@ type Query implements Node { optionalMissingMiddle5(a: Int!, arg1: Int, arg2: Int): Int funcOutUnnamedOutOutUnnamed: FuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" intSetQuery( x: Int y: Int diff --git a/postgraphile/postgraphile/__tests__/schema/v4/rbac.ignore.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/rbac.ignore.1.graphql index 7b280865f9..f1be4b4090 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/rbac.ignore.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/rbac.ignore.1.graphql @@ -7563,7 +7563,7 @@ type Query implements Node { ): FuncOutOutSetofConnection funcOutOutUnnamed: FuncOutOutUnnamedRecord - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcOutSetof( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7635,7 +7635,7 @@ type Query implements Node { offset: Int ): FuncReturnsTableMultiColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcReturnsTableOneCol( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7666,7 +7666,7 @@ type Query implements Node { """Get a single `Input`.""" inputById(id: Int!): Input - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" intSetQuery( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7895,7 +7895,7 @@ type Query implements Node { """Get a single `SimilarTable2`.""" similarTable2ById(id: Int!): SimilarTable2 - """Reads and enables pagination through a set of `Int8`.""" + """Reads and enables pagination through a set of `BigInt`.""" staticBigInteger( """Read all values in the set after (below) this cursor.""" after: Cursor diff --git a/postgraphile/postgraphile/__tests__/schema/v4/relay1.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/relay1.1.export.mjs index 36675bdbe5..fbbfb1f5a9 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/relay1.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/relay1.1.export.mjs @@ -5372,7 +5372,7 @@ type Query implements Node { currentUserId: Int funcOut: Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcOutSetof( """Only read the first \`n\` values of the set.""" first: Int @@ -5396,7 +5396,7 @@ type Query implements Node { noArgsQuery: Int funcInOut(i: Int): Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcReturnsTableOneCol( i: Int @@ -5446,7 +5446,7 @@ type Query implements Node { funcOutOutUnnamed: FuncOutOutUnnamedRecord funcOutUnnamedOutOutUnnamed: FuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" intSetQuery( x: Int y: Int diff --git a/postgraphile/postgraphile/__tests__/schema/v4/relay1.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/relay1.1.graphql index 8c45c20138..1d703f2143 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/relay1.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/relay1.1.graphql @@ -3634,7 +3634,7 @@ type Query implements Node { ): FuncOutOutSetofConnection funcOutOutUnnamed: FuncOutOutUnnamedRecord - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcOutSetof( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -3706,7 +3706,7 @@ type Query implements Node { offset: Int ): FuncReturnsTableMultiColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcReturnsTableOneCol( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -3733,7 +3733,7 @@ type Query implements Node { """ id: ID! - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" intSetQuery( """Read all values in the set after (below) this cursor.""" after: Cursor diff --git a/postgraphile/postgraphile/__tests__/schema/v4/simple-collections.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/simple-collections.1.export.mjs index 0ebb29444c..15becd9d0c 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/simple-collections.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/simple-collections.1.export.mjs @@ -5375,7 +5375,7 @@ type Query implements Node { currentUserId: Int funcOut: Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcOutSetof( """Only read the first \`n\` values of the set.""" first: Int @@ -5406,7 +5406,7 @@ type Query implements Node { noArgsQuery: Int funcInOut(i: Int): Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcReturnsTableOneCol( i: Int @@ -5472,7 +5472,7 @@ type Query implements Node { funcOutOutUnnamed: FuncOutOutUnnamedRecord funcOutUnnamedOutOutUnnamed: FuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" intSetQuery( x: Int y: Int diff --git a/postgraphile/postgraphile/__tests__/schema/v4/simple-collections.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/simple-collections.1.graphql index 84af7bddf8..ade9f5ed77 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/simple-collections.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/simple-collections.1.graphql @@ -3856,7 +3856,7 @@ type Query implements Node { ): [FuncOutOutSetofRecord!] funcOutOutUnnamed: FuncOutOutUnnamedRecord - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcOutSetof( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -3953,7 +3953,7 @@ type Query implements Node { offset: Int ): [FuncReturnsTableMultiColRecord!] - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcReturnsTableOneCol( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -3983,7 +3983,7 @@ type Query implements Node { offset: Int ): [Int!] - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" intSetQuery( """Read all values in the set after (below) this cursor.""" after: Cursor diff --git a/postgraphile/postgraphile/__tests__/schema/v4/simplePrint.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/simplePrint.export.mjs index 1aabb0f777..c42bf086ad 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/simplePrint.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/simplePrint.export.mjs @@ -8995,7 +8995,7 @@ type Query implements Node { currentUserId: Int funcOut: Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcOutSetof( """Only read the first \`n\` values of the set.""" first: Int @@ -9041,7 +9041,7 @@ type Query implements Node { ): QueryIntervalSetConnection queryTextArray: [String] - """Reads and enables pagination through a set of \`Int8\`.""" + """Reads and enables pagination through a set of \`BigInt\`.""" staticBigInteger( """Only read the first \`n\` values of the set.""" first: Int @@ -9063,7 +9063,7 @@ type Query implements Node { ): StaticBigIntegerConnection funcInOut(i: Int): Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcReturnsTableOneCol( i: Int @@ -9137,7 +9137,7 @@ type Query implements Node { optionalMissingMiddle5(a: Int!, arg1: Int, arg2: Int): Int funcOutUnnamedOutOutUnnamed: FuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" intSetQuery( x: Int y: Int diff --git a/postgraphile/postgraphile/__tests__/schema/v4/simplePrint.graphql b/postgraphile/postgraphile/__tests__/schema/v4/simplePrint.graphql index 007cb8c4fc..b137b0087b 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/simplePrint.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/simplePrint.graphql @@ -88,7 +88,7 @@ type Query implements Node { currentUserId: Int funcOut: Int - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcOutSetof( """Only read the first `n` values of the set.""" first: Int @@ -134,7 +134,7 @@ type Query implements Node { ): QueryIntervalSetConnection queryTextArray: [String] - """Reads and enables pagination through a set of `Int8`.""" + """Reads and enables pagination through a set of `BigInt`.""" staticBigInteger( """Only read the first `n` values of the set.""" first: Int @@ -156,7 +156,7 @@ type Query implements Node { ): StaticBigIntegerConnection funcInOut(i: Int): Int - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcReturnsTableOneCol( i: Int @@ -230,7 +230,7 @@ type Query implements Node { optionalMissingMiddle5(a: Int!, arg1: Int, arg2: Int): Int funcOutUnnamedOutOutUnnamed: FuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" intSetQuery( x: Int y: Int diff --git a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.1.export.mjs index 35755eaf94..74a8d8c269 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.1.export.mjs @@ -8557,7 +8557,7 @@ type Query { currentUserId: Int funcOut: Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcOutSetof( """Only read the first \`n\` values of the set.""" first: Int @@ -8603,7 +8603,7 @@ type Query { ): QueryIntervalSetConnection queryTextArray: [String] - """Reads and enables pagination through a set of \`Int8\`.""" + """Reads and enables pagination through a set of \`BigInt\`.""" staticBigInteger( """Only read the first \`n\` values of the set.""" first: Int @@ -8625,7 +8625,7 @@ type Query { ): StaticBigIntegerConnection funcInOut(i: Int): Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" funcReturnsTableOneCol( i: Int @@ -8699,7 +8699,7 @@ type Query { optionalMissingMiddle5(a: Int!, arg1: Int, arg2: Int): Int funcOutUnnamedOutOutUnnamed: FuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" intSetQuery( x: Int y: Int diff --git a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.1.graphql index a7d636dfda..a85ae5c7ed 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.1.graphql @@ -6874,7 +6874,7 @@ type Query { ): FuncOutOutSetofConnection funcOutOutUnnamed: FuncOutOutUnnamedRecord - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcOutSetof( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -6946,7 +6946,7 @@ type Query { offset: Int ): FuncReturnsTableMultiColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" funcReturnsTableOneCol( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -6971,7 +6971,7 @@ type Query { """Get a single `Input`.""" inputById(id: Int!): Input - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" intSetQuery( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7093,7 +7093,7 @@ type Query { """Get a single `SimilarTable2`.""" similarTable2ById(id: Int!): SimilarTable2 - """Reads and enables pagination through a set of `Int8`.""" + """Reads and enables pagination through a set of `BigInt`.""" staticBigInteger( """Read all values in the set after (below) this cursor.""" after: Cursor diff --git a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs index eafc9f884e..a0603c9e1c 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs @@ -2703,6 +2703,7 @@ const single_table_items_resourceOptionsConfig = { }; const all_single_tablesFunctionIdentifer = sql.identifier("polymorphic", "all_single_tables"); const get_single_table_topic_by_idFunctionIdentifer = sql.identifier("polymorphic", "get_single_table_topic_by_id"); +const single_table_items_topicsFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_topics"); const relational_itemsUniques = [{ attributes: ["id"], isPrimary: true @@ -3331,6 +3332,29 @@ const registryConfig = { } } }), + single_table_items_topics: PgResource.functionResourceOptions(single_table_items_resourceOptionsConfig, { + name: "single_table_items_topics", + identifier: "main.polymorphic.single_table_items_topics(polymorphic.single_table_items)", + from(...args) { + return sql`${single_table_items_topicsFunctionIdentifer}(${sqlFromArgDigests(args)})`; + }, + parameters: [{ + name: "sti", + codec: singleTableItemsCodec + }], + returnsSetof: true, + extensions: { + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "single_table_items_topics" + }, + tags: { + returnType: "SingleTableTopic" + } + }, + hasImplicitOrder: true + }), relational_items: relational_items_resourceOptionsConfig, all_relational_items_fn: PgResource.functionResourceOptions(relational_items_resourceOptionsConfig, { name: "all_relational_items_fn", @@ -4033,6 +4057,30 @@ const scalarComputed = (resource, $in, args) => { const single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs = ($in, args, _info) => { return scalarComputed(resource_single_table_items_meaning_of_lifePgResource, $in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); }; +const resource_single_table_items_topicsPgResource = registry.pgResources["single_table_items_topics"]; +const single_table_items_topics_getSelectPlanFromParentAndArgs = ($in, args, _info) => { + const details = pgFunctionArgumentsFromArgs($in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); + return resource_single_table_items_topicsPgResource.execute(details.selectArgs); +}; +function SingleTableTopic_topicsPlan($parent, args, info) { + const $select = single_table_items_topics_getSelectPlanFromParentAndArgs($parent, args, info); + return connection($select); +} +function applyFirstArg(_, $connection, arg) { + $connection.setFirst(arg.getRaw()); +} +function applyLastArg(_, $connection, val) { + $connection.setLast(val.getRaw()); +} +function applyOffsetArg(_, $connection, val) { + $connection.setOffset(val.getRaw()); +} +function applyBeforeArg(_, $connection, val) { + $connection.setBefore(val.getRaw()); +} +function applyAfterArg(_, $connection, val) { + $connection.setAfter(val.getRaw()); +} const SingleTableTopic_parentIdPlan = $record => { return $record.get("parent_id"); }; @@ -4068,21 +4116,6 @@ const SingleTableTopic_singleTableItemsByParentIdPlan = $record => { }); return connection($records); }; -function applyFirstArg(_, $connection, arg) { - $connection.setFirst(arg.getRaw()); -} -function applyLastArg(_, $connection, val) { - $connection.setLast(val.getRaw()); -} -function applyOffsetArg(_, $connection, val) { - $connection.setOffset(val.getRaw()); -} -function applyBeforeArg(_, $connection, val) { - $connection.setBefore(val.getRaw()); -} -function applyAfterArg(_, $connection, val) { - $connection.setAfter(val.getRaw()); -} function qbWhereBuilder(qb) { return qb.whereBuilder(); } @@ -5660,6 +5693,27 @@ function getClientMutationIdForUpdateOrDeletePlan($mutation) { } export const typeDefs = /* GraphQL */`type SingleTableTopic implements SingleTableItem { meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! id: Int! type: ItemType! parentId: Int @@ -7317,6 +7371,34 @@ type SingleTableItemRelationCompositePksEdge { node: SingleTableItemRelationCompositePk } +"""A connection to a list of \`SingleTableTopic\` values.""" +type SingleTableTopicConnection { + """A list of \`SingleTableTopic\` objects.""" + nodes: [SingleTableTopic]! + + """ + A list of edges which contains the \`SingleTableTopic\` and cursor to aid in pagination. + """ + edges: [SingleTableTopicEdge]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* \`SingleTableItem\` you could get from the connection. + """ + totalCount: Int! +} + +"""A \`SingleTableTopic\` edge in the connection.""" +type SingleTableTopicEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The \`SingleTableTopic\` at the end of the edge.""" + node: SingleTableTopic +} + """ A condition to be used against \`SingleTableItemRelation\` object types. All fields are tested for equality and combined with a logical ‘and.’ @@ -7370,6 +7452,27 @@ enum SingleTableItemRelationCompositePksOrderBy { type SingleTablePost implements SingleTableItem { meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! id: Int! type: ItemType! parentId: Int @@ -7591,6 +7694,27 @@ type Priority { type SingleTableDivider implements SingleTableItem { meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! id: Int! type: ItemType! parentId: Int @@ -7773,6 +7897,27 @@ type SingleTableDivider implements SingleTableItem { type SingleTableChecklist implements SingleTableItem { meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! id: Int! type: ItemType! parentId: Int @@ -7959,6 +8104,27 @@ type SingleTableChecklist implements SingleTableItem { type SingleTableChecklistItem implements SingleTableItem { meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! id: Int! type: ItemType! parentId: Int @@ -16945,6 +17111,16 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, @@ -17023,6 +17199,16 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, @@ -17099,6 +17285,16 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, @@ -17230,6 +17426,16 @@ export const objects = { subject($record) { return $record.get("title"); }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, @@ -17306,9 +17512,25 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, + SingleTableTopicConnection: { + assertStep: ConnectionStep, + plans: { + totalCount: totalCountConnectionPlan + } + }, ThirdPartyVulnerabilitiesConnection: { assertStep: ConnectionStep, plans: { diff --git a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql index 7257dac40a..e238384a71 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql @@ -6130,6 +6130,27 @@ type SingleTableChecklist implements SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! title: String + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } @@ -6316,6 +6337,27 @@ type SingleTableChecklistItem implements SingleTableItem { """The method to use when ordering `SingleTableItem`.""" orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } @@ -6498,6 +6540,27 @@ type SingleTableDivider implements SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! title: String + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } @@ -7083,6 +7146,27 @@ type SingleTablePost implements SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! subject: String + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } @@ -7264,10 +7348,59 @@ type SingleTableTopic implements SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! title: String! + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } +"""A connection to a list of `SingleTableTopic` values.""" +type SingleTableTopicConnection { + """ + A list of edges which contains the `SingleTableTopic` and cursor to aid in pagination. + """ + edges: [SingleTableTopicEdge]! + + """A list of `SingleTableTopic` objects.""" + nodes: [SingleTableTopic]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* `SingleTableItem` you could get from the connection. + """ + totalCount: Int! +} + +"""A `SingleTableTopic` edge in the connection.""" +type SingleTableTopicEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The `SingleTableTopic` at the end of the edge.""" + node: SingleTableTopic +} + """A connection to a list of `ThirdPartyVulnerability` values.""" type ThirdPartyVulnerabilitiesConnection { """ diff --git a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.1.export.mjs index fffd27b784..31ba8470a3 100644 --- a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.1.export.mjs @@ -8527,7 +8527,7 @@ type Query { cCurrentUserId: Int cFuncOut: Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" cFuncOutSetof( """Only read the first \`n\` values of the set.""" first: Int @@ -8561,7 +8561,7 @@ type Query { ): QueryIntervalSetConnection queryTextArray: [String] - """Reads and enables pagination through a set of \`Int8\`.""" + """Reads and enables pagination through a set of \`BigInt\`.""" staticBigInteger( """Only read the first \`n\` values of the set.""" first: Int @@ -8577,7 +8577,7 @@ type Query { ): StaticBigIntegerConnection cFuncInOut(i: Int): Int - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" cFuncReturnsTableOneCol( i: Int @@ -8651,7 +8651,7 @@ type Query { optionalMissingMiddle5(a: Int!, arg1: Int, arg2: Int): Int cFuncOutUnnamedOutOutUnnamed: CFuncOutUnnamedOutOutUnnamedRecord - """Reads and enables pagination through a set of \`Int4\`.""" + """Reads and enables pagination through a set of \`Int\`.""" cIntSetQuery( x: Int y: Int diff --git a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.1.graphql b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.1.graphql index 13588b4adb..fa978c062b 100644 --- a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.1.graphql @@ -7480,7 +7480,7 @@ type Query { ): CFuncOutOutSetofConnection cFuncOutOutUnnamed: CFuncOutOutUnnamedRecord - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" cFuncOutSetof( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7534,7 +7534,7 @@ type Query { offset: Int ): CFuncReturnsTableMultiColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" cFuncReturnsTableOneCol( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7550,7 +7550,7 @@ type Query { offset: Int ): CFuncReturnsTableOneColConnection - """Reads and enables pagination through a set of `Int4`.""" + """Reads and enables pagination through a set of `Int`.""" cIntSetQuery( """Read all values in the set after (below) this cursor.""" after: Cursor @@ -7705,7 +7705,7 @@ type Query { """Get a single `SimilarTable2`.""" similarTable2ByRowId(rowId: Int!): SimilarTable2 - """Reads and enables pagination through a set of `Int8`.""" + """Reads and enables pagination through a set of `BigInt`.""" staticBigInteger( """Read all values in the set after (below) this cursor.""" after: Cursor diff --git a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs index 0d1973824c..ef08378c27 100644 --- a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs @@ -2697,6 +2697,7 @@ const single_table_items_resourceOptionsConfig = { }; const all_single_tablesFunctionIdentifer = sql.identifier("polymorphic", "all_single_tables"); const get_single_table_topic_by_idFunctionIdentifer = sql.identifier("polymorphic", "get_single_table_topic_by_id"); +const single_table_items_topicsFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_topics"); const relational_itemsUniques = [{ attributes: ["id"], isPrimary: true @@ -3325,6 +3326,29 @@ const registryConfig = { } } }), + single_table_items_topics: PgResource.functionResourceOptions(single_table_items_resourceOptionsConfig, { + name: "single_table_items_topics", + identifier: "main.polymorphic.single_table_items_topics(polymorphic.single_table_items)", + from(...args) { + return sql`${single_table_items_topicsFunctionIdentifer}(${sqlFromArgDigests(args)})`; + }, + parameters: [{ + name: "sti", + codec: singleTableItemsCodec + }], + returnsSetof: true, + extensions: { + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "single_table_items_topics" + }, + tags: { + returnType: "SingleTableTopic" + } + }, + hasImplicitOrder: true + }), relational_items: relational_items_resourceOptionsConfig, all_relational_items_fn: PgResource.functionResourceOptions(relational_items_resourceOptionsConfig, { name: "all_relational_items_fn", @@ -4027,6 +4051,24 @@ const scalarComputed = (resource, $in, args) => { const single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs = ($in, args, _info) => { return scalarComputed(resource_single_table_items_meaning_of_lifePgResource, $in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); }; +const resource_single_table_items_topicsPgResource = registry.pgResources["single_table_items_topics"]; +const single_table_items_topics_getSelectPlanFromParentAndArgs = ($in, args, _info) => { + const details = pgFunctionArgumentsFromArgs($in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); + return resource_single_table_items_topicsPgResource.execute(details.selectArgs); +}; +function SingleTableTopic_topicsPlan($parent, args, info) { + const $select = single_table_items_topics_getSelectPlanFromParentAndArgs($parent, args, info); + return connection($select); +} +function applyFirstArg(_, $connection, arg) { + $connection.setFirst(arg.getRaw()); +} +function applyOffsetArg(_, $connection, val) { + $connection.setOffset(val.getRaw()); +} +function applyAfterArg(_, $connection, val) { + $connection.setAfter(val.getRaw()); +} const SingleTableTopic_rowIdPlan = $record => { return $record.get("id"); }; @@ -4065,21 +4107,12 @@ const SingleTableTopic_singleTableItemsByParentIdPlan = $record => { }); return connection($records); }; -function applyFirstArg(_, $connection, arg) { - $connection.setFirst(arg.getRaw()); -} function applyLastArg(_, $connection, val) { $connection.setLast(val.getRaw()); } -function applyOffsetArg(_, $connection, val) { - $connection.setOffset(val.getRaw()); -} function applyBeforeArg(_, $connection, val) { $connection.setBefore(val.getRaw()); } -function applyAfterArg(_, $connection, val) { - $connection.setAfter(val.getRaw()); -} function qbWhereBuilder(qb) { return qb.whereBuilder(); } @@ -5728,6 +5761,21 @@ function getClientMutationIdForUpdateOrDeletePlan($mutation) { } export const typeDefs = /* GraphQL */`type SingleTableTopic implements SingleTableItem { meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! rowId: Int! type: ItemType! parentId: Int @@ -8011,6 +8059,34 @@ type SingleTableItemRelationCompositePkEdge { node: SingleTableItemRelationCompositePk } +"""A connection to a list of \`SingleTableTopic\` values.""" +type SingleTableTopicConnection { + """A list of \`SingleTableTopic\` objects.""" + nodes: [SingleTableTopic]! + + """ + A list of edges which contains the \`SingleTableTopic\` and cursor to aid in pagination. + """ + edges: [SingleTableTopicEdge]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* \`SingleTableItem\` you could get from the connection. + """ + totalCount: Int! +} + +"""A \`SingleTableTopic\` edge in the connection.""" +type SingleTableTopicEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The \`SingleTableTopic\` at the end of the edge.""" + node: SingleTableTopic +} + """ A condition to be used against \`SingleTableItemRelation\` object types. All fields are tested for equality and combined with a logical ‘and.’ @@ -8064,6 +8140,21 @@ enum SingleTableItemRelationCompositePkOrderBy { type SingleTablePost implements SingleTableItem { meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! rowId: Int! type: ItemType! parentId: Int @@ -8285,6 +8376,21 @@ type Priority { type SingleTableDivider implements SingleTableItem { meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! rowId: Int! type: ItemType! parentId: Int @@ -8467,6 +8573,21 @@ type SingleTableDivider implements SingleTableItem { type SingleTableChecklist implements SingleTableItem { meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! rowId: Int! type: ItemType! parentId: Int @@ -8653,6 +8774,21 @@ type SingleTableChecklist implements SingleTableItem { type SingleTableChecklistItem implements SingleTableItem { meaningOfLife: Int + + """Reads and enables pagination through a set of \`SingleTableTopic\`.""" + topics( + """Only read the first \`n\` values of the set.""" + first: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTableTopicConnection! rowId: Int! type: ItemType! parentId: Int @@ -18959,6 +19095,14 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + offset: applyOffsetArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, @@ -19038,6 +19182,14 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + offset: applyOffsetArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, @@ -19115,6 +19267,14 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + offset: applyOffsetArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, @@ -19248,6 +19408,14 @@ export const objects = { subject($record) { return $record.get("title"); }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + offset: applyOffsetArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, @@ -19325,9 +19493,23 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + topics: { + plan: SingleTableTopic_topicsPlan, + args: { + first: applyFirstArg, + offset: applyOffsetArg, + after: applyAfterArg + } + }, updatedAt: SingleTableTopic_updatedAtPlan } }, + SingleTableTopicConnection: { + assertStep: ConnectionStep, + plans: { + totalCount: totalCountConnectionPlan + } + }, ThirdPartyVulnerability: { assertStep: assertPgClassSingleStep, plans: { diff --git a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql index 9a559d4c51..a9b7e28642 100644 --- a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql @@ -7272,6 +7272,21 @@ type SingleTableChecklist implements SingleTableItem { orderBy: [SingleTableItemOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemConnection! title: String + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } @@ -7458,6 +7473,21 @@ type SingleTableChecklistItem implements SingleTableItem { """The method to use when ordering `SingleTableItem`.""" orderBy: [SingleTableItemOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemConnection! + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } @@ -7640,6 +7670,21 @@ type SingleTableDivider implements SingleTableItem { orderBy: [SingleTableItemOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemConnection! title: String + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } @@ -8223,6 +8268,21 @@ type SingleTablePost implements SingleTableItem { orderBy: [SingleTableItemOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemConnection! subject: String + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } @@ -8404,10 +8464,53 @@ type SingleTableTopic implements SingleTableItem { orderBy: [SingleTableItemOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemConnection! title: String! + + """Reads and enables pagination through a set of `SingleTableTopic`.""" + topics( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTableTopicConnection! type: ItemType! updatedAt: Datetime! } +"""A connection to a list of `SingleTableTopic` values.""" +type SingleTableTopicConnection { + """ + A list of edges which contains the `SingleTableTopic` and cursor to aid in pagination. + """ + edges: [SingleTableTopicEdge]! + + """A list of `SingleTableTopic` objects.""" + nodes: [SingleTableTopic]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* `SingleTableItem` you could get from the connection. + """ + totalCount: Int! +} + +"""A `SingleTableTopic` edge in the connection.""" +type SingleTableTopicEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The `SingleTableTopic` at the end of the edge.""" + node: SingleTableTopic +} + type ThirdPartyVulnerability implements Vulnerability { """Reads and enables pagination through a set of `Application`.""" applications( From e52366a8c33758c7322f3c0935006e222c8fe65c Mon Sep 17 00:00:00 2001 From: tsnobip Date: Fri, 5 Jun 2026 15:10:48 +0200 Subject: [PATCH 2/6] Make returnType work for foreign keys --- .../src/plugins/PgRelationsPlugin.ts | 11 +- .../__tests__/kitchen-sink-data.sql | 5 + .../__tests__/kitchen-sink-schema.sql | 11 + .../polymorphic/return-type-foreign-key.json5 | 41 ++ .../return-type-foreign-key.mermaid | 71 ++++ .../polymorphic/return-type-foreign-key.sql | 11 + .../return-type-foreign-key.test.graphql | 24 ++ ...mple-single-table-items-root-topic.mermaid | 375 +++++++++--------- .../polymorphic-auto-add-types.1.export.mjs | 194 +++++++++ .../v4/polymorphic-auto-add-types.1.graphql | 64 +++ .../schema/v4/polymorphic.1.export.mjs | 228 +++++++++++ .../__tests__/schema/v4/polymorphic.1.graphql | 79 ++++ .../skipNodePlugin.polymorphic.1.export.mjs | 194 +++++++++ .../v4/skipNodePlugin.polymorphic.1.graphql | 64 +++ .../skipNodePlugin.polymorphic.1.export.mjs | 195 +++++++++ .../v5/skipNodePlugin.polymorphic.1.graphql | 64 +++ 16 files changed, 1446 insertions(+), 185 deletions(-) create mode 100644 postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.json5 create mode 100644 postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.mermaid create mode 100644 postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.sql create mode 100644 postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.test.graphql diff --git a/graphile-build/graphile-build-pg/src/plugins/PgRelationsPlugin.ts b/graphile-build/graphile-build-pg/src/plugins/PgRelationsPlugin.ts index 4b917c8254..5c9414abb5 100644 --- a/graphile-build/graphile-build-pg/src/plugins/PgRelationsPlugin.ts +++ b/graphile-build/graphile-build-pg/src/plugins/PgRelationsPlugin.ts @@ -933,10 +933,15 @@ function addRelations( } const isUnique = relation.isUnique ?? false; + const preferredTypeName = !relation.isReferencee + ? tagToString(relation.extensions?.tags?.returnType) + : null; const otherCodec = remoteResource.codec; - const typeName = build.inflection.tableType(otherCodec); - const connectionTypeName = - build.inflection.tableConnectionType(otherCodec); + const typeName = + preferredTypeName ?? build.inflection.tableType(otherCodec); + const connectionTypeName = preferredTypeName + ? build.inflection.connectionType(preferredTypeName) + : build.inflection.tableConnectionType(otherCodec); const deprecationReason = tagToString(relation.extensions?.tags?.deprecated) ?? diff --git a/postgraphile/postgraphile/__tests__/kitchen-sink-data.sql b/postgraphile/postgraphile/__tests__/kitchen-sink-data.sql index 3af36646a0..6516fd14c4 100644 --- a/postgraphile/postgraphile/__tests__/kitchen-sink-data.sql +++ b/postgraphile/postgraphile/__tests__/kitchen-sink-data.sql @@ -630,6 +630,11 @@ update polymorphic.single_table_items where single_table_items.id = cte.id and cte.id != cte.rti; +insert into polymorphic.foreign_key_return_type_tests + (id, topic_id) values + (1, 1); +alter sequence polymorphic.foreign_key_return_type_tests_id_seq restart with 9999; + insert into polymorphic.single_table_item_relations (id, parent_id, child_id) values (1, 1, 3), diff --git a/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql b/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql index 99bc9bb0db..cadab7ffaa 100644 --- a/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql +++ b/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql @@ -1462,6 +1462,17 @@ comment on constraint single_table_items_root_topic_fkey on polymorphic.single_t @behavior -* $$; +create table polymorphic.foreign_key_return_type_tests ( + id serial primary key, + topic_id int constraint foreign_key_return_type_tests_topic_fkey references polymorphic.single_table_items on delete cascade +); +comment on table polymorphic.foreign_key_return_type_tests is E'@behavior -insert -update -delete -filter -filterBy -order -orderBy'; +comment on constraint foreign_key_return_type_tests_topic_fkey on polymorphic.foreign_key_return_type_tests is $$ + @behavior -manyRelation:resource:list -manyRelation:resource:connection + @fieldName topicByReturnType + @returnType SingleTableTopic + $$; + create table polymorphic.single_table_item_relations ( id serial primary key, parent_id int not null references polymorphic.single_table_items on delete cascade, diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.json5 b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.json5 new file mode 100644 index 0000000000..579dbb9850 --- /dev/null +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.json5 @@ -0,0 +1,41 @@ +{ + __type: { + fields: [ + { + name: "nodeId", + type: { + name: null, + }, + }, + { + name: "id", + type: { + name: null, + }, + }, + { + name: "topicId", + type: { + name: "Int", + }, + }, + { + name: "topicByReturnType", + type: { + name: "SingleTableTopic", + }, + }, + ], + }, + allForeignKeyReturnTypeTests: { + nodes: [ + { + id: 1, + topicByReturnType: { + id: 1, + title: "PostGraphile version 5", + }, + }, + ], + }, +} diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.mermaid b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.mermaid new file mode 100644 index 0000000000..3d9d7fd3ee --- /dev/null +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.mermaid @@ -0,0 +1,71 @@ +%%{init: {'themeVariables': { 'fontSize': '12px'}}}%% +graph TD + classDef path fill:#eee,stroke:#000,color:#000 + classDef plan fill:#fff,stroke-width:1px,color:#000 + classDef itemplan fill:#fff,stroke-width:2px,color:#000 + classDef unbatchedplan fill:#dff,stroke-width:1px,color:#000 + classDef sideeffectplan fill:#fcc,stroke-width:2px,color:#000 + classDef bucket fill:#f6f6f6,color:#000,stroke-width:2px,text-align:left + + subgraph "Buckets for queries/polymorphic/return-type-foreign-key" + Bucket0("Bucket 0 (root)

1: PgSelectInlineApply[28]
ᐳ: Access[8], Access[9], Object[10]
2: PgSelect[7]
ᐳ: Access[29]
3: Connection[11]
4: ConnectionItems[12]"):::bucket + Bucket1("Bucket 1 (nullableBoundary)
Deps: 11, 12, 29

ROOT Connectionᐸ7ᐳ[11]"):::bucket + Bucket3("Bucket 3 (listItem)
Deps: 29

ROOT __Item{3}ᐸ12ᐳ[15]"):::bucket + Bucket4("Bucket 4 (nullableBoundary)
Deps: 16, 29

ROOT PgSelectSingle{3}ᐸforeign_key_return_type_testsᐳ[16]
1:
ᐳ: 17, 30, 31
2: PgSelectRows[24]
ᐳ: First[23], PgSelectSingle[25]"):::bucket + Bucket5("Bucket 5 (nullableBoundary)
Deps: 25

ROOT PgSelectSingle{4}ᐸsingle_table_itemsᐳ[25]"):::bucket + end + Bucket0 --> Bucket1 + Bucket1 --> Bucket3 + Bucket3 --> Bucket4 + Bucket4 --> Bucket5 + + %% plan dependencies + PgSelect7[["PgSelect[7∈0] ➊
ᐸforeign_key_return_type_testsᐳ"]]:::plan + Object10{{"Object[10∈0] ➊
ᐸ{pgSettings,withPgClient}ᐳ"}}:::plan + PgSelectInlineApply28["PgSelectInlineApply[28∈0] ➊"]:::plan + Object10 & PgSelectInlineApply28 --> PgSelect7 + Access8{{"Access[8∈0] ➊
ᐸ2.pgSettingsᐳ"}}:::plan + Access9{{"Access[9∈0] ➊
ᐸ2.withPgClientᐳ"}}:::plan + Access8 & Access9 --> Object10 + __Value2["__Value[2∈0] ➊
ᐸcontextᐳ"]:::plan + __Value2 --> Access8 + __Value2 --> Access9 + Connection11[["Connection[11∈0] ➊
ᐸ7ᐳ"]]:::plan + PgSelect7 --> Connection11 + ConnectionItems12[["ConnectionItems[12∈0] ➊"]]:::plan + Connection11 --> ConnectionItems12 + Access29{{"Access[29∈0] ➊
ᐸ7.m.joinDetailsFor19ᐳ"}}:::plan + PgSelect7 --> Access29 + __Item15[/"__Item[15∈3]
ᐸ12ᐳ"\]:::itemplan + ConnectionItems12 ==> __Item15 + PgSelectSingle16{{"PgSelectSingle[16∈3]
ᐸforeign_key_return_type_testsᐳ"}}:::plan + __Item15 --> PgSelectSingle16 + List30{{"List[30∈4]
ᐸ29,16ᐳ"}}:::plan + Access29 & PgSelectSingle16 --> List30 + PgClassExpression17{{"PgClassExpression[17∈4]
ᐸ__foreign_...sts__.”id”ᐳ"}}:::plan + PgSelectSingle16 --> PgClassExpression17 + First23{{"First[23∈4]"}}:::plan + PgSelectRows24[["PgSelectRows[24∈4]"]]:::plan + PgSelectRows24 --> First23 + Lambda31{{"Lambda[31∈4]
ᐸpgInlineViaJoinTransformᐳ"}}:::plan + Lambda31 --> PgSelectRows24 + PgSelectSingle25{{"PgSelectSingle[25∈4]
ᐸsingle_table_itemsᐳ"}}:::plan + First23 --> PgSelectSingle25 + List30 --> Lambda31 + PgClassExpression26{{"PgClassExpression[26∈5]
ᐸ__single_t...ems__.”id”ᐳ"}}:::plan + PgSelectSingle25 --> PgClassExpression26 + PgClassExpression27{{"PgClassExpression[27∈5]
ᐸ__single_t...__.”title”ᐳ"}}:::plan + PgClassExpression26 o--o PgClassExpression27 + + %% define steps + classDef bucket0 stroke:#696969 + class Bucket0,__Value2,PgSelect7,Access8,Access9,Object10,Connection11,ConnectionItems12,PgSelectInlineApply28,Access29 bucket0 + classDef bucket1 stroke:#00bfff + class Bucket1 bucket1 + classDef bucket3 stroke:#ffa500 + class Bucket3,__Item15,PgSelectSingle16 bucket3 + classDef bucket4 stroke:#0000ff + class Bucket4,PgClassExpression17,First23,PgSelectRows24,PgSelectSingle25,List30,Lambda31 bucket4 + classDef bucket5 stroke:#7fff00 + class Bucket5,PgClassExpression26,PgClassExpression27 bucket5 + diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.sql b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.sql new file mode 100644 index 0000000000..8422b8a6c1 --- /dev/null +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.sql @@ -0,0 +1,11 @@ +select + __foreign_key_return_type_tests__."id"::text as "0", + __single_table_items__."id"::text as "1", + __single_table_items__."title" as "2" +from "polymorphic"."foreign_key_return_type_tests" as __foreign_key_return_type_tests__ +left outer join "polymorphic"."single_table_items" as __single_table_items__ +on ( +/* WHERE becoming ON */ ( + __single_table_items__."id" = __foreign_key_return_type_tests__."topic_id" +)) +order by __foreign_key_return_type_tests__."id" asc; \ No newline at end of file diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.test.graphql b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.test.graphql new file mode 100644 index 0000000000..021c582fcf --- /dev/null +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.test.graphql @@ -0,0 +1,24 @@ +## expect(errors).toBeFalsy() +## expect(JSON.stringify(data.__type.fields)).toContain("SingleTableTopic") +#> schema: ["polymorphic"] +#> simpleCollections: "both" + +{ + __type(name: "ForeignKeyReturnTypeTest") { + fields { + name + type { + name + } + } + } + allForeignKeyReturnTypeTests { + nodes { + id + topicByReturnType { + id + title + } + } + } +} diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/simple-single-table-items-root-topic.mermaid b/postgraphile/postgraphile/__tests__/queries/polymorphic/simple-single-table-items-root-topic.mermaid index 711be10f5c..83d7a50503 100644 --- a/postgraphile/postgraphile/__tests__/queries/polymorphic/simple-single-table-items-root-topic.mermaid +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/simple-single-table-items-root-topic.mermaid @@ -8,54 +8,55 @@ graph TD classDef bucket fill:#f6f6f6,color:#000,stroke-width:2px,text-align:left subgraph "Buckets for queries/polymorphic/simple-single-table-items-root-topic" - Bucket0("Bucket 0 (root)

1: 376, 380
ᐳ: 9, 10, 275, 315, 318, 323, 326, 390, 11, 15, 16, 24, 25
2: PgSelect[8], PgSelect[18]
ᐳ: Access[377], Access[381]
3: Connection[12], PgSelectRows[21]
ᐳ: First[20], PgSelectSingle[22]
4: ConnectionItems[271]"):::bucket - Bucket1("Bucket 1 (nullableBoundary)
Deps: 12, 377, 271, 315, 318, 275, 323, 326

ROOT Connectionᐸ8ᐳ[12]"):::bucket - Bucket2("Bucket 2 (nullableBoundary)
Deps: 22, 275, 381

ROOT PgSelectSingleᐸsingle_table_itemsᐳ[22]
1:
ᐳ: 274, 278, 279, 382, 276, 277, 383
2: PgSelectRows[285]
ᐳ: First[284], PgSelectSingle[286]"):::bucket - Bucket3("Bucket 3 (polymorphic)
__typename: Lambda[25]
Deps: 24, 25, 11, 275, 4"):::bucket - Bucket4("Bucket 4 (polymorphicPartition)
|SingleTableTopic
|SingleTablePost
|SingleTableDivider
|SingleTableChecklist
|SingleTableChecklistItem
Deps: 11, 388, 275
ᐳSingleTableTopic
ᐳSingleTablePost
ᐳSingleTableDivider
ᐳSingleTableChecklist
ᐳSingleTableChecklistItem

1: PgSelectInlineApply[384]
2: PgSelect[29]
ᐳ: Access[385]
3: PgSelectRows[34]
ᐳ: 33, 35, 287, 288, 289, 290, 291, 386, 387
4: PgSelectRows[297]
ᐳ: First[296], PgSelectSingle[298]"):::bucket - Bucket5("Bucket 5 (polymorphicPartition)
|Person
Deps: 11, 388
ᐳPerson

1: PgSelect[39]
2: PgSelectRows[44]
ᐳ: First[43], PgSelectSingle[45]"):::bucket - Bucket6("Bucket 6 (polymorphicPartition)
|LogEntry
Deps: 11, 388
ᐳLogEntry

1: PgSelect[49]
2: PgSelectRows[54]
ᐳ: First[53], PgSelectSingle[55]"):::bucket - Bucket7("Bucket 7 (polymorphicPartition)
|Organization
Deps: 11, 388
ᐳOrganization

1: PgSelect[59]
2: PgSelectRows[64]
ᐳ: First[63], PgSelectSingle[65]"):::bucket - Bucket8("Bucket 8 (polymorphicPartition)
|AwsApplication
Deps: 11, 388
ᐳAwsApplication

1: PgSelect[69]
2: PgSelectRows[74]
ᐳ: First[73], PgSelectSingle[75]"):::bucket - Bucket9("Bucket 9 (polymorphicPartition)
|GcpApplication
Deps: 11, 388
ᐳGcpApplication

1: PgSelect[79]
2: PgSelectRows[84]
ᐳ: First[83], PgSelectSingle[85]"):::bucket - Bucket10("Bucket 10 (polymorphicPartition)
|RelationalItemRelation
Deps: 11, 388
ᐳRelationalItemRelation

1: PgSelect[89]
2: PgSelectRows[94]
ᐳ: First[93], PgSelectSingle[95]"):::bucket - Bucket11("Bucket 11 (polymorphicPartition)
|RelationalItemRelationCompositePk
Deps: 11, 388, 389
ᐳRelationalItemRelationCompositePk

1: PgSelect[101]
2: PgSelectRows[106]
ᐳ: First[105], PgSelectSingle[107]"):::bucket - Bucket12("Bucket 12 (polymorphicPartition)
|SingleTableItemRelation
Deps: 11, 388
ᐳSingleTableItemRelation

1: PgSelect[111]
2: PgSelectRows[116]
ᐳ: First[115], PgSelectSingle[117]"):::bucket - Bucket13("Bucket 13 (polymorphicPartition)
|SingleTableItemRelationCompositePk
Deps: 11, 388, 389
ᐳSingleTableItemRelationCompositePk

1: PgSelect[123]
2: PgSelectRows[128]
ᐳ: First[127], PgSelectSingle[129]"):::bucket - Bucket14("Bucket 14 (polymorphicPartition)
|Priority
Deps: 11, 388
ᐳPriority

1: PgSelect[143]
2: PgSelectRows[148]
ᐳ: First[147], PgSelectSingle[149]"):::bucket - Bucket15("Bucket 15 (polymorphicPartition)
|RelationalTopic
Deps: 11, 388
ᐳRelationalTopic

1: PgSelect[183]
2: PgSelectRows[188]
ᐳ: First[187], PgSelectSingle[189]"):::bucket - Bucket16("Bucket 16 (polymorphicPartition)
|RelationalPost
Deps: 11, 388
ᐳRelationalPost

1: PgSelect[193]
2: PgSelectRows[198]
ᐳ: First[197], PgSelectSingle[199]"):::bucket - Bucket17("Bucket 17 (polymorphicPartition)
|RelationalDivider
Deps: 11, 388
ᐳRelationalDivider

1: PgSelect[203]
2: PgSelectRows[208]
ᐳ: First[207], PgSelectSingle[209]"):::bucket - Bucket18("Bucket 18 (polymorphicPartition)
|RelationalChecklist
Deps: 11, 388
ᐳRelationalChecklist

1: PgSelect[213]
2: PgSelectRows[218]
ᐳ: First[217], PgSelectSingle[219]"):::bucket - Bucket19("Bucket 19 (polymorphicPartition)
|RelationalChecklistItem
Deps: 11, 388
ᐳRelationalChecklistItem

1: PgSelect[223]
2: PgSelectRows[228]
ᐳ: First[227], PgSelectSingle[229]"):::bucket - Bucket20("Bucket 20 (polymorphicPartition)
|MovieCollection
|SeriesCollection
Deps: 11, 388
ᐳMovieCollection
ᐳSeriesCollection

1: PgSelect[233]
2: PgSelectRows[238]
ᐳ: First[237], PgSelectSingle[239]"):::bucket + Bucket0("Bucket 0 (root)

1: 386, 390
ᐳ: 9, 10, 285, 325, 328, 333, 336, 400, 11, 15, 16, 24, 25
2: PgSelect[8], PgSelect[18]
ᐳ: Access[387], Access[391]
3: Connection[12], PgSelectRows[21]
ᐳ: First[20], PgSelectSingle[22]
4: ConnectionItems[281]"):::bucket + Bucket1("Bucket 1 (nullableBoundary)
Deps: 12, 387, 281, 325, 328, 285, 333, 336

ROOT Connectionᐸ8ᐳ[12]"):::bucket + Bucket2("Bucket 2 (nullableBoundary)
Deps: 22, 285, 391

ROOT PgSelectSingleᐸsingle_table_itemsᐳ[22]
1:
ᐳ: 284, 288, 289, 392, 286, 287, 393
2: PgSelectRows[295]
ᐳ: First[294], PgSelectSingle[296]"):::bucket + Bucket3("Bucket 3 (polymorphic)
__typename: Lambda[25]
Deps: 24, 25, 11, 285, 4"):::bucket + Bucket4("Bucket 4 (polymorphicPartition)
|SingleTableTopic
|SingleTablePost
|SingleTableDivider
|SingleTableChecklist
|SingleTableChecklistItem
Deps: 11, 398, 285
ᐳSingleTableTopic
ᐳSingleTablePost
ᐳSingleTableDivider
ᐳSingleTableChecklist
ᐳSingleTableChecklistItem

1: PgSelectInlineApply[394]
2: PgSelect[29]
ᐳ: Access[395]
3: PgSelectRows[34]
ᐳ: 33, 35, 297, 298, 299, 300, 301, 396, 397
4: PgSelectRows[307]
ᐳ: First[306], PgSelectSingle[308]"):::bucket + Bucket5("Bucket 5 (polymorphicPartition)
|Person
Deps: 11, 398
ᐳPerson

1: PgSelect[39]
2: PgSelectRows[44]
ᐳ: First[43], PgSelectSingle[45]"):::bucket + Bucket6("Bucket 6 (polymorphicPartition)
|LogEntry
Deps: 11, 398
ᐳLogEntry

1: PgSelect[49]
2: PgSelectRows[54]
ᐳ: First[53], PgSelectSingle[55]"):::bucket + Bucket7("Bucket 7 (polymorphicPartition)
|Organization
Deps: 11, 398
ᐳOrganization

1: PgSelect[59]
2: PgSelectRows[64]
ᐳ: First[63], PgSelectSingle[65]"):::bucket + Bucket8("Bucket 8 (polymorphicPartition)
|AwsApplication
Deps: 11, 398
ᐳAwsApplication

1: PgSelect[69]
2: PgSelectRows[74]
ᐳ: First[73], PgSelectSingle[75]"):::bucket + Bucket9("Bucket 9 (polymorphicPartition)
|GcpApplication
Deps: 11, 398
ᐳGcpApplication

1: PgSelect[79]
2: PgSelectRows[84]
ᐳ: First[83], PgSelectSingle[85]"):::bucket + Bucket10("Bucket 10 (polymorphicPartition)
|RelationalItemRelation
Deps: 11, 398
ᐳRelationalItemRelation

1: PgSelect[89]
2: PgSelectRows[94]
ᐳ: First[93], PgSelectSingle[95]"):::bucket + Bucket11("Bucket 11 (polymorphicPartition)
|RelationalItemRelationCompositePk
Deps: 11, 398, 399
ᐳRelationalItemRelationCompositePk

1: PgSelect[101]
2: PgSelectRows[106]
ᐳ: First[105], PgSelectSingle[107]"):::bucket + Bucket12("Bucket 12 (polymorphicPartition)
|SingleTableItemRelation
Deps: 11, 398
ᐳSingleTableItemRelation

1: PgSelect[111]
2: PgSelectRows[116]
ᐳ: First[115], PgSelectSingle[117]"):::bucket + Bucket13("Bucket 13 (polymorphicPartition)
|SingleTableItemRelationCompositePk
Deps: 11, 398, 399
ᐳSingleTableItemRelationCompositePk

1: PgSelect[123]
2: PgSelectRows[128]
ᐳ: First[127], PgSelectSingle[129]"):::bucket + Bucket14("Bucket 14 (polymorphicPartition)
|Priority
Deps: 11, 398
ᐳPriority

1: PgSelect[143]
2: PgSelectRows[148]
ᐳ: First[147], PgSelectSingle[149]"):::bucket + Bucket15("Bucket 15 (polymorphicPartition)
|RelationalTopic
Deps: 11, 398
ᐳRelationalTopic

1: PgSelect[183]
2: PgSelectRows[188]
ᐳ: First[187], PgSelectSingle[189]"):::bucket + Bucket16("Bucket 16 (polymorphicPartition)
|RelationalPost
Deps: 11, 398
ᐳRelationalPost

1: PgSelect[193]
2: PgSelectRows[198]
ᐳ: First[197], PgSelectSingle[199]"):::bucket + Bucket17("Bucket 17 (polymorphicPartition)
|RelationalDivider
Deps: 11, 398
ᐳRelationalDivider

1: PgSelect[203]
2: PgSelectRows[208]
ᐳ: First[207], PgSelectSingle[209]"):::bucket + Bucket18("Bucket 18 (polymorphicPartition)
|RelationalChecklist
Deps: 11, 398
ᐳRelationalChecklist

1: PgSelect[213]
2: PgSelectRows[218]
ᐳ: First[217], PgSelectSingle[219]"):::bucket + Bucket19("Bucket 19 (polymorphicPartition)
|RelationalChecklistItem
Deps: 11, 398
ᐳRelationalChecklistItem

1: PgSelect[223]
2: PgSelectRows[228]
ᐳ: First[227], PgSelectSingle[229]"):::bucket + Bucket20("Bucket 20 (polymorphicPartition)
|MovieCollection
|SeriesCollection
Deps: 11, 398
ᐳMovieCollection
ᐳSeriesCollection

1: PgSelect[233]
2: PgSelectRows[238]
ᐳ: First[237], PgSelectSingle[239]"):::bucket Bucket21("Bucket 21 (polymorphicPartition)
|Query
Deps: 4
ᐳQuery"):::bucket - Bucket22("Bucket 22 (polymorphicPartition)
|FirstPartyVulnerability
Deps: 11, 388
ᐳFirstPartyVulnerability

1: PgSelect[254]
2: PgSelectRows[259]
ᐳ: First[258], PgSelectSingle[260]"):::bucket - Bucket23("Bucket 23 (polymorphicPartition)
|ThirdPartyVulnerability
Deps: 11, 388
ᐳThirdPartyVulnerability

1: PgSelect[264]
2: PgSelectRows[269]
ᐳ: First[268], PgSelectSingle[270]"):::bucket - Bucket25("Bucket 25 (nullableBoundary)
Deps: 286

ROOT PgSelectSingle{2}ᐸsingle_table_itemsᐳ[286]"):::bucket - Bucket26("Bucket 26 (listItem)
Deps: 377, 315, 318, 275, 323, 326

ROOT __Item{26}ᐸ271ᐳ[299]
1:
ᐳ: 300, 303, 306, 307, 334, 378, 379
2: PgSelectRows[344]
ᐳ: First[343], PgSelectSingle[345]"):::bucket - Bucket27("Bucket 27 (nullableBoundary)
Deps: 298

ROOT PgSelectSingle{4}ᐸsingle_table_itemsᐳ[298]"):::bucket - Bucket28("Bucket 28 (polymorphic)
__typename: Lambda[307]
Deps: 315, 303, 318, 275, 323, 326, 307, 345, 300, 306, 334"):::bucket - Bucket29("Bucket 29 (nullableBoundary)
Deps: 345

ROOT PgSelectSingle{26}ᐸsingle_table_itemsᐳ[345]"):::bucket + Bucket22("Bucket 22 (polymorphicPartition)
|ForeignKeyReturnTypeTest
Deps: 11, 398
ᐳForeignKeyReturnTypeTest

1: PgSelect[254]
2: PgSelectRows[259]
ᐳ: First[258], PgSelectSingle[260]"):::bucket + Bucket23("Bucket 23 (polymorphicPartition)
|FirstPartyVulnerability
Deps: 11, 398
ᐳFirstPartyVulnerability

1: PgSelect[264]
2: PgSelectRows[269]
ᐳ: First[268], PgSelectSingle[270]"):::bucket + Bucket24("Bucket 24 (polymorphicPartition)
|ThirdPartyVulnerability
Deps: 11, 398
ᐳThirdPartyVulnerability

1: PgSelect[274]
2: PgSelectRows[279]
ᐳ: First[278], PgSelectSingle[280]"):::bucket + Bucket26("Bucket 26 (nullableBoundary)
Deps: 296

ROOT PgSelectSingle{2}ᐸsingle_table_itemsᐳ[296]"):::bucket + Bucket27("Bucket 27 (listItem)
Deps: 387, 325, 328, 285, 333, 336

ROOT __Item{27}ᐸ281ᐳ[309]
1:
ᐳ: 310, 313, 316, 317, 344, 388, 389
2: PgSelectRows[354]
ᐳ: First[353], PgSelectSingle[355]"):::bucket + Bucket28("Bucket 28 (nullableBoundary)
Deps: 308

ROOT PgSelectSingle{4}ᐸsingle_table_itemsᐳ[308]"):::bucket + Bucket29("Bucket 29 (polymorphic)
__typename: Lambda[317]
Deps: 325, 313, 328, 285, 333, 336, 317, 355, 310, 316, 344"):::bucket + Bucket30("Bucket 30 (nullableBoundary)
Deps: 355

ROOT PgSelectSingle{27}ᐸsingle_table_itemsᐳ[355]"):::bucket end Bucket0 --> Bucket1 & Bucket2 & Bucket3 - Bucket1 --> Bucket26 - Bucket2 --> Bucket25 - Bucket3 --> Bucket4 & Bucket5 & Bucket6 & Bucket7 & Bucket8 & Bucket9 & Bucket10 & Bucket11 & Bucket12 & Bucket13 & Bucket14 & Bucket15 & Bucket16 & Bucket17 & Bucket18 & Bucket19 & Bucket20 & Bucket21 & Bucket22 & Bucket23 - Bucket4 --> Bucket27 - Bucket26 --> Bucket28 - Bucket28 --> Bucket29 + Bucket1 --> Bucket27 + Bucket2 --> Bucket26 + Bucket3 --> Bucket4 & Bucket5 & Bucket6 & Bucket7 & Bucket8 & Bucket9 & Bucket10 & Bucket11 & Bucket12 & Bucket13 & Bucket14 & Bucket15 & Bucket16 & Bucket17 & Bucket18 & Bucket19 & Bucket20 & Bucket21 & Bucket22 & Bucket23 & Bucket24 + Bucket4 --> Bucket28 + Bucket27 --> Bucket29 + Bucket29 --> Bucket30 %% plan dependencies PgSelect18[["PgSelect[18∈0] ➊
ᐸsingle_table_itemsᐳ
More deps:
- Object[11]"]]:::plan Access16{{"Access[16∈0] ➊
ᐸ15.1ᐳ"}}:::plan - PgSelectInlineApply380["PgSelectInlineApply[380∈0] ➊"]:::plan + PgSelectInlineApply390["PgSelectInlineApply[390∈0] ➊"]:::plan Access16 -->|rejectNull| PgSelect18 - PgSelectInlineApply380 --> PgSelect18 + PgSelectInlineApply390 --> PgSelect18 PgSelect8[["PgSelect[8∈0] ➊
ᐸsingle_table_itemsᐳ
More deps:
- Object[11]"]]:::plan - PgSelectInlineApply376["PgSelectInlineApply[376∈0] ➊"]:::plan - PgSelectInlineApply376 --> PgSelect8 - Object11{{"Object[11∈0] ➊
ᐸ{pgSettings,withPgClient}ᐳ
Dependents: 21"}}:::plan + PgSelectInlineApply386["PgSelectInlineApply[386∈0] ➊"]:::plan + PgSelectInlineApply386 --> PgSelect8 + Object11{{"Object[11∈0] ➊
ᐸ{pgSettings,withPgClient}ᐳ
Dependents: 22"}}:::plan Access9{{"Access[9∈0] ➊
ᐸ2.pgSettingsᐳ"}}:::plan Access10{{"Access[10∈0] ➊
ᐸ2.withPgClientᐳ"}}:::plan Access9 & Access10 --> Object11 @@ -64,7 +65,7 @@ graph TD __Value2 --> Access10 Connection12[["Connection[12∈0] ➊
ᐸ8ᐳ"]]:::plan PgSelect8 --> Connection12 - Lambda15{{"Lambda[15∈0] ➊
ᐸspecifier_SingleTableDivider_base64JSONᐳ
More deps:
- Constantᐸ'WyJTaW5nbGVUYWJsZURpdmlkZXIiLDNd'ᐳ[390]"}}:::plan + Lambda15{{"Lambda[15∈0] ➊
ᐸspecifier_SingleTableDivider_base64JSONᐳ
More deps:
- Constantᐸ'WyJTaW5nbGVUYWJsZURpdmlkZXIiLDNd'ᐳ[400]"}}:::plan Lambda15 --> Access16 First20{{"First[20∈0] ➊"}}:::plan PgSelectRows21[["PgSelectRows[21∈0] ➊"]]:::plan @@ -72,69 +73,69 @@ graph TD PgSelect18 --> PgSelectRows21 PgSelectSingle22{{"PgSelectSingle[22∈0] ➊
ᐸsingle_table_itemsᐳ"}}:::plan First20 --> PgSelectSingle22 - Lambda24{{"Lambda[24∈0] ➊
ᐸdecodeNodeIdWithCodecsᐳ
Dependents: 3
More deps:
- Constantᐸ'WyJTaW5nbGVUYWJsZURpdmlkZXIiLDNd'ᐳ[390]"}}:::plan - ConnectionItems271[["ConnectionItems[271∈0] ➊"]]:::plan - Connection12 --> ConnectionItems271 - Access377{{"Access[377∈0] ➊
ᐸ8.m.joinDetailsFor339ᐳ"}}:::plan - PgSelect8 --> Access377 - Access381{{"Access[381∈0] ➊
ᐸ18.m.joinDetailsFor280ᐳ"}}:::plan - PgSelect18 --> Access381 - List276{{"List[276∈2] ➊
ᐸ275,274ᐳ
More deps:
- Constantᐸ'SingleTableDivider'ᐳ[275]"}}:::plan - PgClassExpression274{{"PgClassExpression[274∈2] ➊
ᐸ__single_t...ems__.”id”ᐳ"}}:::plan - PgClassExpression274 --> List276 - List382{{"List[382∈2] ➊
ᐸ381,22ᐳ"}}:::plan - Access381 & PgSelectSingle22 --> List382 - PgSelectSingle22 --> PgClassExpression274 - Lambda277{{"Lambda[277∈2] ➊
ᐸbase64JSONEncodeᐳ"}}:::plan - List276 --> Lambda277 - PgClassExpression278{{"PgClassExpression[278∈2] ➊
ᐸ__single_t...s__.”type”ᐳ"}}:::plan - PgSelectSingle22 --> PgClassExpression278 - PgClassExpression279{{"PgClassExpression[279∈2] ➊
ᐸ__single_t..._topic_id”ᐳ"}}:::plan - PgClassExpression278 o--o PgClassExpression279 - First284{{"First[284∈2] ➊"}}:::plan - PgSelectRows285[["PgSelectRows[285∈2] ➊"]]:::plan - PgSelectRows285 --> First284 - Lambda383{{"Lambda[383∈2] ➊
ᐸpgInlineViaJoinTransformᐳ"}}:::plan - Lambda383 --> PgSelectRows285 - PgSelectSingle286{{"PgSelectSingle[286∈2] ➊
ᐸsingle_table_itemsᐳ"}}:::plan - First284 --> PgSelectSingle286 - List382 --> Lambda383 - Access388{{"Access[388∈3] ➊
ᐸ24.base64JSON.1ᐳ
ᐳSingleTableTopic
ᐳPerson
ᐳLogEntry
ᐳOrganization
ᐳAwsApplication
ᐳGcpApplication
ᐳRelationalItemRelation
ᐳRelationalItemRelationCompositePk
ᐳSingleTableItemRelation
ᐳSingleTableItemRelationCompositePk
ᐳSingleTablePost
ᐳPriority
ᐳSingleTableDivider
ᐳSingleTableChecklist
ᐳSingleTableChecklistItem
ᐳRelationalTopic
ᐳRelationalPost
ᐳRelationalDivider
ᐳRelationalChecklist
ᐳRelationalChecklistItem
ᐳMovieCollection
ᐳSeriesCollection
ᐳFirstPartyVulnerability
ᐳThirdPartyVulnerability
More deps:
- Lambda[24]"}}:::plan - Access389{{"Access[389∈3] ➊
ᐸ24.base64JSON.2ᐳ
ᐳRelationalItemRelationCompositePk
ᐳSingleTableItemRelationCompositePk
More deps:
- Lambda[24]"}}:::plan + Lambda24{{"Lambda[24∈0] ➊
ᐸdecodeNodeIdWithCodecsᐳ
Dependents: 3
More deps:
- Constantᐸ'WyJTaW5nbGVUYWJsZURpdmlkZXIiLDNd'ᐳ[400]"}}:::plan + ConnectionItems281[["ConnectionItems[281∈0] ➊"]]:::plan + Connection12 --> ConnectionItems281 + Access387{{"Access[387∈0] ➊
ᐸ8.m.joinDetailsFor349ᐳ"}}:::plan + PgSelect8 --> Access387 + Access391{{"Access[391∈0] ➊
ᐸ18.m.joinDetailsFor290ᐳ"}}:::plan + PgSelect18 --> Access391 + List286{{"List[286∈2] ➊
ᐸ285,284ᐳ
More deps:
- Constantᐸ'SingleTableDivider'ᐳ[285]"}}:::plan + PgClassExpression284{{"PgClassExpression[284∈2] ➊
ᐸ__single_t...ems__.”id”ᐳ"}}:::plan + PgClassExpression284 --> List286 + List392{{"List[392∈2] ➊
ᐸ391,22ᐳ"}}:::plan + Access391 & PgSelectSingle22 --> List392 + PgSelectSingle22 --> PgClassExpression284 + Lambda287{{"Lambda[287∈2] ➊
ᐸbase64JSONEncodeᐳ"}}:::plan + List286 --> Lambda287 + PgClassExpression288{{"PgClassExpression[288∈2] ➊
ᐸ__single_t...s__.”type”ᐳ"}}:::plan + PgSelectSingle22 --> PgClassExpression288 + PgClassExpression289{{"PgClassExpression[289∈2] ➊
ᐸ__single_t..._topic_id”ᐳ"}}:::plan + PgClassExpression288 o--o PgClassExpression289 + First294{{"First[294∈2] ➊"}}:::plan + PgSelectRows295[["PgSelectRows[295∈2] ➊"]]:::plan + PgSelectRows295 --> First294 + Lambda393{{"Lambda[393∈2] ➊
ᐸpgInlineViaJoinTransformᐳ"}}:::plan + Lambda393 --> PgSelectRows295 + PgSelectSingle296{{"PgSelectSingle[296∈2] ➊
ᐸsingle_table_itemsᐳ"}}:::plan + First294 --> PgSelectSingle296 + List392 --> Lambda393 + Access398{{"Access[398∈3] ➊
ᐸ24.base64JSON.1ᐳ
ᐳSingleTableTopic
ᐳPerson
ᐳLogEntry
ᐳOrganization
ᐳAwsApplication
ᐳGcpApplication
ᐳRelationalItemRelation
ᐳRelationalItemRelationCompositePk
ᐳSingleTableItemRelation
ᐳSingleTableItemRelationCompositePk
ᐳSingleTablePost
ᐳPriority
ᐳSingleTableDivider
ᐳSingleTableChecklist
ᐳSingleTableChecklistItem
ᐳRelationalTopic
ᐳRelationalPost
ᐳRelationalDivider
ᐳRelationalChecklist
ᐳRelationalChecklistItem
ᐳMovieCollection
ᐳSeriesCollection
ᐳForeignKeyReturnTypeTest
ᐳFirstPartyVulnerability
ᐳThirdPartyVulnerability
More deps:
- Lambda[24]"}}:::plan + Access399{{"Access[399∈3] ➊
ᐸ24.base64JSON.2ᐳ
ᐳRelationalItemRelationCompositePk
ᐳSingleTableItemRelationCompositePk
More deps:
- Lambda[24]"}}:::plan PgSelect29[["PgSelect[29∈4] ➊^
ᐸsingle_table_itemsᐳ
More deps:
- Object[11]"]]:::plan - PgSelectInlineApply384["PgSelectInlineApply[384∈4] ➊
ᐳSingleTableTopic
ᐳSingleTablePost
ᐳSingleTableDivider
ᐳSingleTableChecklist
ᐳSingleTableChecklistItem"]:::plan - Access388 -->|rejectNull| PgSelect29 - PgSelectInlineApply384 --> PgSelect29 - List288{{"List[288∈4] ➊^
ᐸ275,287ᐳ
More deps:
- Constantᐸ'SingleTableDivider'ᐳ[275]"}}:::plan - PgClassExpression287{{"PgClassExpression[287∈4] ➊
ᐸ__single_t...ems__.”id”ᐳ
ᐳSingleTableDivider"}}:::plan - PgClassExpression287 --> List288 - List386{{"List[386∈4] ➊
ᐸ385,35ᐳ
ᐳSingleTableDivider"}}:::plan - Access385{{"Access[385∈4] ➊
ᐸ29.m.joinDetailsFor292ᐳ
ᐳSingleTableDivider"}}:::plan + PgSelectInlineApply394["PgSelectInlineApply[394∈4] ➊
ᐳSingleTableTopic
ᐳSingleTablePost
ᐳSingleTableDivider
ᐳSingleTableChecklist
ᐳSingleTableChecklistItem"]:::plan + Access398 -->|rejectNull| PgSelect29 + PgSelectInlineApply394 --> PgSelect29 + List298{{"List[298∈4] ➊^
ᐸ285,297ᐳ
More deps:
- Constantᐸ'SingleTableDivider'ᐳ[285]"}}:::plan + PgClassExpression297{{"PgClassExpression[297∈4] ➊
ᐸ__single_t...ems__.”id”ᐳ
ᐳSingleTableDivider"}}:::plan + PgClassExpression297 --> List298 + List396{{"List[396∈4] ➊
ᐸ395,35ᐳ
ᐳSingleTableDivider"}}:::plan + Access395{{"Access[395∈4] ➊
ᐸ29.m.joinDetailsFor302ᐳ
ᐳSingleTableDivider"}}:::plan PgSelectSingle35{{"PgSelectSingle[35∈4] ➊^
ᐸsingle_table_itemsᐳ"}}:::plan - Access385 & PgSelectSingle35 --> List386 + Access395 & PgSelectSingle35 --> List396 First33{{"First[33∈4] ➊^"}}:::plan PgSelectRows34[["PgSelectRows[34∈4] ➊^"]]:::plan PgSelectRows34 --> First33 PgSelect29 --> PgSelectRows34 First33 --> PgSelectSingle35 - PgSelectSingle35 --> PgClassExpression287 - Lambda289{{"Lambda[289∈4] ➊^
ᐸbase64JSONEncodeᐳ"}}:::plan - List288 --> Lambda289 - PgClassExpression290{{"PgClassExpression[290∈4] ➊
ᐸ__single_t...s__.”type”ᐳ
ᐳSingleTableDivider"}}:::plan - PgSelectSingle35 --> PgClassExpression290 - PgClassExpression291{{"PgClassExpression[291∈4] ➊
ᐸ__single_t..._topic_id”ᐳ
ᐳSingleTableDivider"}}:::plan - PgClassExpression290 o--o PgClassExpression291 - First296{{"First[296∈4] ➊^"}}:::plan - PgSelectRows297[["PgSelectRows[297∈4] ➊^"]]:::plan - PgSelectRows297 --> First296 - Lambda387{{"Lambda[387∈4] ➊^
ᐸpgInlineViaJoinTransformᐳ"}}:::plan - Lambda387 --> PgSelectRows297 - PgSelectSingle298{{"PgSelectSingle[298∈4] ➊^
ᐸsingle_table_itemsᐳ"}}:::plan - First296 --> PgSelectSingle298 - PgSelect29 --> Access385 - List386 --> Lambda387 + PgSelectSingle35 --> PgClassExpression297 + Lambda299{{"Lambda[299∈4] ➊^
ᐸbase64JSONEncodeᐳ"}}:::plan + List298 --> Lambda299 + PgClassExpression300{{"PgClassExpression[300∈4] ➊
ᐸ__single_t...s__.”type”ᐳ
ᐳSingleTableDivider"}}:::plan + PgSelectSingle35 --> PgClassExpression300 + PgClassExpression301{{"PgClassExpression[301∈4] ➊
ᐸ__single_t..._topic_id”ᐳ
ᐳSingleTableDivider"}}:::plan + PgClassExpression300 o--o PgClassExpression301 + First306{{"First[306∈4] ➊^"}}:::plan + PgSelectRows307[["PgSelectRows[307∈4] ➊^"]]:::plan + PgSelectRows307 --> First306 + Lambda397{{"Lambda[397∈4] ➊^
ᐸpgInlineViaJoinTransformᐳ"}}:::plan + Lambda397 --> PgSelectRows307 + PgSelectSingle308{{"PgSelectSingle[308∈4] ➊^
ᐸsingle_table_itemsᐳ"}}:::plan + First306 --> PgSelectSingle308 + PgSelect29 --> Access395 + List396 --> Lambda397 PgSelect39[["PgSelect[39∈5] ➊
ᐸpeopleᐳ
ᐳPerson
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect39 + Access398 -->|rejectNull| PgSelect39 First43{{"First[43∈5] ➊^"}}:::plan PgSelectRows44[["PgSelectRows[44∈5] ➊^"]]:::plan PgSelectRows44 --> First43 @@ -142,7 +143,7 @@ graph TD PgSelectSingle45{{"PgSelectSingle[45∈5] ➊^
ᐸpeopleᐳ"}}:::plan First43 --> PgSelectSingle45 PgSelect49[["PgSelect[49∈6] ➊
ᐸlog_entriesᐳ
ᐳLogEntry
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect49 + Access398 -->|rejectNull| PgSelect49 First53{{"First[53∈6] ➊^"}}:::plan PgSelectRows54[["PgSelectRows[54∈6] ➊^"]]:::plan PgSelectRows54 --> First53 @@ -150,7 +151,7 @@ graph TD PgSelectSingle55{{"PgSelectSingle[55∈6] ➊^
ᐸlog_entriesᐳ"}}:::plan First53 --> PgSelectSingle55 PgSelect59[["PgSelect[59∈7] ➊
ᐸorganizationsᐳ
ᐳOrganization
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect59 + Access398 -->|rejectNull| PgSelect59 First63{{"First[63∈7] ➊^"}}:::plan PgSelectRows64[["PgSelectRows[64∈7] ➊^"]]:::plan PgSelectRows64 --> First63 @@ -158,7 +159,7 @@ graph TD PgSelectSingle65{{"PgSelectSingle[65∈7] ➊^
ᐸorganizationsᐳ"}}:::plan First63 --> PgSelectSingle65 PgSelect69[["PgSelect[69∈8] ➊
ᐸaws_applicationsᐳ
ᐳAwsApplication
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect69 + Access398 -->|rejectNull| PgSelect69 First73{{"First[73∈8] ➊^"}}:::plan PgSelectRows74[["PgSelectRows[74∈8] ➊^"]]:::plan PgSelectRows74 --> First73 @@ -166,7 +167,7 @@ graph TD PgSelectSingle75{{"PgSelectSingle[75∈8] ➊^
ᐸaws_applicationsᐳ"}}:::plan First73 --> PgSelectSingle75 PgSelect79[["PgSelect[79∈9] ➊
ᐸgcp_applicationsᐳ
ᐳGcpApplication
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect79 + Access398 -->|rejectNull| PgSelect79 First83{{"First[83∈9] ➊^"}}:::plan PgSelectRows84[["PgSelectRows[84∈9] ➊^"]]:::plan PgSelectRows84 --> First83 @@ -174,7 +175,7 @@ graph TD PgSelectSingle85{{"PgSelectSingle[85∈9] ➊^
ᐸgcp_applicationsᐳ"}}:::plan First83 --> PgSelectSingle85 PgSelect89[["PgSelect[89∈10] ➊
ᐸrelational_item_relationsᐳ
ᐳRelationalItemRelation
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect89 + Access398 -->|rejectNull| PgSelect89 First93{{"First[93∈10] ➊^"}}:::plan PgSelectRows94[["PgSelectRows[94∈10] ➊^"]]:::plan PgSelectRows94 --> First93 @@ -182,8 +183,8 @@ graph TD PgSelectSingle95{{"PgSelectSingle[95∈10] ➊^
ᐸrelational_item_relationsᐳ"}}:::plan First93 --> PgSelectSingle95 PgSelect101[["PgSelect[101∈11] ➊
ᐸrelational_item_relation_composite_pksᐳ
ᐳRelationalItemRelationCompositePk
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect101 - Access389 -->|rejectNull| PgSelect101 + Access398 -->|rejectNull| PgSelect101 + Access399 -->|rejectNull| PgSelect101 First105{{"First[105∈11] ➊^"}}:::plan PgSelectRows106[["PgSelectRows[106∈11] ➊^"]]:::plan PgSelectRows106 --> First105 @@ -191,7 +192,7 @@ graph TD PgSelectSingle107{{"PgSelectSingle[107∈11] ➊^
ᐸrelational_item_relation_composite_pksᐳ"}}:::plan First105 --> PgSelectSingle107 PgSelect111[["PgSelect[111∈12] ➊
ᐸsingle_table_item_relationsᐳ
ᐳSingleTableItemRelation
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect111 + Access398 -->|rejectNull| PgSelect111 First115{{"First[115∈12] ➊^"}}:::plan PgSelectRows116[["PgSelectRows[116∈12] ➊^"]]:::plan PgSelectRows116 --> First115 @@ -199,8 +200,8 @@ graph TD PgSelectSingle117{{"PgSelectSingle[117∈12] ➊^
ᐸsingle_table_item_relationsᐳ"}}:::plan First115 --> PgSelectSingle117 PgSelect123[["PgSelect[123∈13] ➊
ᐸsingle_table_item_relation_composite_pksᐳ
ᐳSingleTableItemRelationCompositePk
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect123 - Access389 -->|rejectNull| PgSelect123 + Access398 -->|rejectNull| PgSelect123 + Access399 -->|rejectNull| PgSelect123 First127{{"First[127∈13] ➊^"}}:::plan PgSelectRows128[["PgSelectRows[128∈13] ➊^"]]:::plan PgSelectRows128 --> First127 @@ -208,7 +209,7 @@ graph TD PgSelectSingle129{{"PgSelectSingle[129∈13] ➊^
ᐸsingle_table_item_relation_composite_pksᐳ"}}:::plan First127 --> PgSelectSingle129 PgSelect143[["PgSelect[143∈14] ➊
ᐸprioritiesᐳ
ᐳPriority
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect143 + Access398 -->|rejectNull| PgSelect143 First147{{"First[147∈14] ➊^"}}:::plan PgSelectRows148[["PgSelectRows[148∈14] ➊^"]]:::plan PgSelectRows148 --> First147 @@ -216,7 +217,7 @@ graph TD PgSelectSingle149{{"PgSelectSingle[149∈14] ➊^
ᐸprioritiesᐳ"}}:::plan First147 --> PgSelectSingle149 PgSelect183[["PgSelect[183∈15] ➊
ᐸrelational_topicsᐳ
ᐳRelationalTopic
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect183 + Access398 -->|rejectNull| PgSelect183 First187{{"First[187∈15] ➊^"}}:::plan PgSelectRows188[["PgSelectRows[188∈15] ➊^"]]:::plan PgSelectRows188 --> First187 @@ -224,7 +225,7 @@ graph TD PgSelectSingle189{{"PgSelectSingle[189∈15] ➊^
ᐸrelational_topicsᐳ"}}:::plan First187 --> PgSelectSingle189 PgSelect193[["PgSelect[193∈16] ➊
ᐸrelational_postsᐳ
ᐳRelationalPost
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect193 + Access398 -->|rejectNull| PgSelect193 First197{{"First[197∈16] ➊^"}}:::plan PgSelectRows198[["PgSelectRows[198∈16] ➊^"]]:::plan PgSelectRows198 --> First197 @@ -232,7 +233,7 @@ graph TD PgSelectSingle199{{"PgSelectSingle[199∈16] ➊^
ᐸrelational_postsᐳ"}}:::plan First197 --> PgSelectSingle199 PgSelect203[["PgSelect[203∈17] ➊
ᐸrelational_dividersᐳ
ᐳRelationalDivider
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect203 + Access398 -->|rejectNull| PgSelect203 First207{{"First[207∈17] ➊^"}}:::plan PgSelectRows208[["PgSelectRows[208∈17] ➊^"]]:::plan PgSelectRows208 --> First207 @@ -240,7 +241,7 @@ graph TD PgSelectSingle209{{"PgSelectSingle[209∈17] ➊^
ᐸrelational_dividersᐳ"}}:::plan First207 --> PgSelectSingle209 PgSelect213[["PgSelect[213∈18] ➊
ᐸrelational_checklistsᐳ
ᐳRelationalChecklist
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect213 + Access398 -->|rejectNull| PgSelect213 First217{{"First[217∈18] ➊^"}}:::plan PgSelectRows218[["PgSelectRows[218∈18] ➊^"]]:::plan PgSelectRows218 --> First217 @@ -248,7 +249,7 @@ graph TD PgSelectSingle219{{"PgSelectSingle[219∈18] ➊^
ᐸrelational_checklistsᐳ"}}:::plan First217 --> PgSelectSingle219 PgSelect223[["PgSelect[223∈19] ➊
ᐸrelational_checklist_itemsᐳ
ᐳRelationalChecklistItem
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect223 + Access398 -->|rejectNull| PgSelect223 First227{{"First[227∈19] ➊^"}}:::plan PgSelectRows228[["PgSelectRows[228∈19] ➊^"]]:::plan PgSelectRows228 --> First227 @@ -256,95 +257,103 @@ graph TD PgSelectSingle229{{"PgSelectSingle[229∈19] ➊^
ᐸrelational_checklist_itemsᐳ"}}:::plan First227 --> PgSelectSingle229 PgSelect233[["PgSelect[233∈20] ➊
ᐸcollectionsᐳ
ᐳMovieCollection
ᐳSeriesCollection
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect233 + Access398 -->|rejectNull| PgSelect233 First237{{"First[237∈20] ➊^"}}:::plan PgSelectRows238[["PgSelectRows[238∈20] ➊^"]]:::plan PgSelectRows238 --> First237 PgSelect233 --> PgSelectRows238 PgSelectSingle239{{"PgSelectSingle[239∈20] ➊^
ᐸcollectionsᐳ"}}:::plan First237 --> PgSelectSingle239 - PgSelect254[["PgSelect[254∈22] ➊
ᐸfirst_party_vulnerabilitiesᐳ
ᐳFirstPartyVulnerability
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect254 + PgSelect254[["PgSelect[254∈22] ➊
ᐸforeign_key_return_type_testsᐳ
ᐳForeignKeyReturnTypeTest
More deps:
- Object[11]"]]:::plan + Access398 -->|rejectNull| PgSelect254 First258{{"First[258∈22] ➊^"}}:::plan PgSelectRows259[["PgSelectRows[259∈22] ➊^"]]:::plan PgSelectRows259 --> First258 PgSelect254 --> PgSelectRows259 - PgSelectSingle260{{"PgSelectSingle[260∈22] ➊^
ᐸfirst_party_vulnerabilitiesᐳ"}}:::plan + PgSelectSingle260{{"PgSelectSingle[260∈22] ➊^
ᐸforeign_key_return_type_testsᐳ"}}:::plan First258 --> PgSelectSingle260 - PgSelect264[["PgSelect[264∈23] ➊
ᐸthird_party_vulnerabilitiesᐳ
ᐳThirdPartyVulnerability
More deps:
- Object[11]"]]:::plan - Access388 -->|rejectNull| PgSelect264 + PgSelect264[["PgSelect[264∈23] ➊
ᐸfirst_party_vulnerabilitiesᐳ
ᐳFirstPartyVulnerability
More deps:
- Object[11]"]]:::plan + Access398 -->|rejectNull| PgSelect264 First268{{"First[268∈23] ➊^"}}:::plan PgSelectRows269[["PgSelectRows[269∈23] ➊^"]]:::plan PgSelectRows269 --> First268 PgSelect264 --> PgSelectRows269 - PgSelectSingle270{{"PgSelectSingle[270∈23] ➊^
ᐸthird_party_vulnerabilitiesᐳ"}}:::plan + PgSelectSingle270{{"PgSelectSingle[270∈23] ➊^
ᐸfirst_party_vulnerabilitiesᐳ"}}:::plan First268 --> PgSelectSingle270 - PgClassExpression301{{"PgClassExpression[301∈25] ➊
ᐸ__single_t...ems__.”id”ᐳ"}}:::plan - PgSelectSingle286 --> PgClassExpression301 - PgClassExpression302{{"PgClassExpression[302∈25] ➊
ᐸ__single_t...__.”title”ᐳ"}}:::plan - PgClassExpression301 o--o PgClassExpression302 - List378{{"List[378∈26]
ᐸ377,300ᐳ"}}:::plan - PgSelectSingle300{{"PgSelectSingle[300∈26]
ᐸsingle_table_itemsᐳ"}}:::plan - Access377 & PgSelectSingle300 --> List378 - __Item299[/"__Item[299∈26]
ᐸ271ᐳ"\]:::itemplan - ConnectionItems271 ==> __Item299 - __Item299 --> PgSelectSingle300 - PgClassExpression303{{"PgClassExpression[303∈26]
ᐸ__single_t...ems__.”id”ᐳ"}}:::plan - PgSelectSingle300 --> PgClassExpression303 - PgClassExpression306{{"PgClassExpression[306∈26]
ᐸ__single_t...s__.”type”ᐳ"}}:::plan - PgSelectSingle300 --> PgClassExpression306 - Lambda307{{"Lambda[307∈26]
ᐸSingleTableItem_typeNameFromTypeᐳ"}}:::plan - PgClassExpression306 --> Lambda307 - PgClassExpression334{{"PgClassExpression[334∈26]
ᐸ__single_t..._topic_id”ᐳ"}}:::plan - PgSelectSingle300 --> PgClassExpression334 - First343{{"First[343∈26]"}}:::plan - PgSelectRows344[["PgSelectRows[344∈26]"]]:::plan - PgSelectRows344 --> First343 - Lambda379{{"Lambda[379∈26]
ᐸpgInlineViaJoinTransformᐳ"}}:::plan - Lambda379 --> PgSelectRows344 - PgSelectSingle345{{"PgSelectSingle[345∈26]
ᐸsingle_table_itemsᐳ"}}:::plan - First343 --> PgSelectSingle345 - List378 --> Lambda379 - PgClassExpression308{{"PgClassExpression[308∈27] ➊
ᐸ__single_t...ems__.”id”ᐳ
ᐳSingleTableDivider"}}:::plan - PgSelectSingle298 --> PgClassExpression308 - PgClassExpression309{{"PgClassExpression[309∈27] ➊
ᐸ__single_t...__.”title”ᐳ
ᐳSingleTableDivider"}}:::plan - PgClassExpression308 o--o PgClassExpression309 - List316{{"List[316∈28]
ᐸ315,303ᐳ
ᐳSingleTableTopic
More deps:
- Constantᐸ'SingleTableTopic'ᐳ[315]"}}:::plan - PgClassExpression303 --> List316 - List319{{"List[319∈28]
ᐸ318,303ᐳ
ᐳSingleTablePost
More deps:
- Constantᐸ'SingleTablePost'ᐳ[318]"}}:::plan - PgClassExpression303 --> List319 - List321{{"List[321∈28]
ᐸ275,303ᐳ
ᐳSingleTableDivider
More deps:
- Constantᐸ'SingleTableDivider'ᐳ[275]"}}:::plan - PgClassExpression303 --> List321 - List324{{"List[324∈28]
ᐸ323,303ᐳ
ᐳSingleTableChecklist
More deps:
- Constantᐸ'SingleTableChecklist'ᐳ[323]"}}:::plan - PgClassExpression303 --> List324 - List327{{"List[327∈28]
ᐸ326,303ᐳ
ᐳSingleTableChecklistItem
More deps:
- Constantᐸ'SingleTableChecklistItem'ᐳ[326]"}}:::plan - PgClassExpression303 --> List327 - Lambda317{{"Lambda[317∈28]^
ᐸbase64JSONEncodeᐳ"}}:::plan - List316 --> Lambda317 - Lambda320{{"Lambda[320∈28]^
ᐸbase64JSONEncodeᐳ"}}:::plan - List319 --> Lambda320 - Lambda322{{"Lambda[322∈28]^
ᐸbase64JSONEncodeᐳ"}}:::plan - List321 --> Lambda322 - Lambda325{{"Lambda[325∈28]^
ᐸbase64JSONEncodeᐳ"}}:::plan - List324 --> Lambda325 - Lambda328{{"Lambda[328∈28]^
ᐸbase64JSONEncodeᐳ"}}:::plan - List327 --> Lambda328 - PgClassExpression374{{"PgClassExpression[374∈29]
ᐸ__single_t...ems__.”id”ᐳ
ᐳSingleTableTopic
ᐳSingleTablePost
ᐳSingleTableDivider
ᐳSingleTableChecklist
ᐳSingleTableChecklistItem"}}:::plan - PgSelectSingle345 --> PgClassExpression374 - PgClassExpression375{{"PgClassExpression[375∈29]
ᐸ__single_t...__.”title”ᐳ
ᐳSingleTableTopic
ᐳSingleTablePost
ᐳSingleTableDivider
ᐳSingleTableChecklist
ᐳSingleTableChecklistItem"}}:::plan - PgClassExpression374 o--o PgClassExpression375 + PgSelect274[["PgSelect[274∈24] ➊
ᐸthird_party_vulnerabilitiesᐳ
ᐳThirdPartyVulnerability
More deps:
- Object[11]"]]:::plan + Access398 -->|rejectNull| PgSelect274 + First278{{"First[278∈24] ➊^"}}:::plan + PgSelectRows279[["PgSelectRows[279∈24] ➊^"]]:::plan + PgSelectRows279 --> First278 + PgSelect274 --> PgSelectRows279 + PgSelectSingle280{{"PgSelectSingle[280∈24] ➊^
ᐸthird_party_vulnerabilitiesᐳ"}}:::plan + First278 --> PgSelectSingle280 + PgClassExpression311{{"PgClassExpression[311∈26] ➊
ᐸ__single_t...ems__.”id”ᐳ"}}:::plan + PgSelectSingle296 --> PgClassExpression311 + PgClassExpression312{{"PgClassExpression[312∈26] ➊
ᐸ__single_t...__.”title”ᐳ"}}:::plan + PgClassExpression311 o--o PgClassExpression312 + List388{{"List[388∈27]
ᐸ387,310ᐳ"}}:::plan + PgSelectSingle310{{"PgSelectSingle[310∈27]
ᐸsingle_table_itemsᐳ"}}:::plan + Access387 & PgSelectSingle310 --> List388 + __Item309[/"__Item[309∈27]
ᐸ281ᐳ"\]:::itemplan + ConnectionItems281 ==> __Item309 + __Item309 --> PgSelectSingle310 + PgClassExpression313{{"PgClassExpression[313∈27]
ᐸ__single_t...ems__.”id”ᐳ"}}:::plan + PgSelectSingle310 --> PgClassExpression313 + PgClassExpression316{{"PgClassExpression[316∈27]
ᐸ__single_t...s__.”type”ᐳ"}}:::plan + PgSelectSingle310 --> PgClassExpression316 + Lambda317{{"Lambda[317∈27]
ᐸSingleTableItem_typeNameFromTypeᐳ"}}:::plan + PgClassExpression316 --> Lambda317 + PgClassExpression344{{"PgClassExpression[344∈27]
ᐸ__single_t..._topic_id”ᐳ"}}:::plan + PgSelectSingle310 --> PgClassExpression344 + First353{{"First[353∈27]"}}:::plan + PgSelectRows354[["PgSelectRows[354∈27]"]]:::plan + PgSelectRows354 --> First353 + Lambda389{{"Lambda[389∈27]
ᐸpgInlineViaJoinTransformᐳ"}}:::plan + Lambda389 --> PgSelectRows354 + PgSelectSingle355{{"PgSelectSingle[355∈27]
ᐸsingle_table_itemsᐳ"}}:::plan + First353 --> PgSelectSingle355 + List388 --> Lambda389 + PgClassExpression318{{"PgClassExpression[318∈28] ➊
ᐸ__single_t...ems__.”id”ᐳ
ᐳSingleTableDivider"}}:::plan + PgSelectSingle308 --> PgClassExpression318 + PgClassExpression319{{"PgClassExpression[319∈28] ➊
ᐸ__single_t...__.”title”ᐳ
ᐳSingleTableDivider"}}:::plan + PgClassExpression318 o--o PgClassExpression319 + List326{{"List[326∈29]
ᐸ325,313ᐳ
ᐳSingleTableTopic
More deps:
- Constantᐸ'SingleTableTopic'ᐳ[325]"}}:::plan + PgClassExpression313 --> List326 + List329{{"List[329∈29]
ᐸ328,313ᐳ
ᐳSingleTablePost
More deps:
- Constantᐸ'SingleTablePost'ᐳ[328]"}}:::plan + PgClassExpression313 --> List329 + List331{{"List[331∈29]
ᐸ285,313ᐳ
ᐳSingleTableDivider
More deps:
- Constantᐸ'SingleTableDivider'ᐳ[285]"}}:::plan + PgClassExpression313 --> List331 + List334{{"List[334∈29]
ᐸ333,313ᐳ
ᐳSingleTableChecklist
More deps:
- Constantᐸ'SingleTableChecklist'ᐳ[333]"}}:::plan + PgClassExpression313 --> List334 + List337{{"List[337∈29]
ᐸ336,313ᐳ
ᐳSingleTableChecklistItem
More deps:
- Constantᐸ'SingleTableChecklistItem'ᐳ[336]"}}:::plan + PgClassExpression313 --> List337 + Lambda327{{"Lambda[327∈29]^
ᐸbase64JSONEncodeᐳ"}}:::plan + List326 --> Lambda327 + Lambda330{{"Lambda[330∈29]^
ᐸbase64JSONEncodeᐳ"}}:::plan + List329 --> Lambda330 + Lambda332{{"Lambda[332∈29]^
ᐸbase64JSONEncodeᐳ"}}:::plan + List331 --> Lambda332 + Lambda335{{"Lambda[335∈29]^
ᐸbase64JSONEncodeᐳ"}}:::plan + List334 --> Lambda335 + Lambda338{{"Lambda[338∈29]^
ᐸbase64JSONEncodeᐳ"}}:::plan + List337 --> Lambda338 + PgClassExpression384{{"PgClassExpression[384∈30]
ᐸ__single_t...ems__.”id”ᐳ
ᐳSingleTableTopic
ᐳSingleTablePost
ᐳSingleTableDivider
ᐳSingleTableChecklist
ᐳSingleTableChecklistItem"}}:::plan + PgSelectSingle355 --> PgClassExpression384 + PgClassExpression385{{"PgClassExpression[385∈30]
ᐸ__single_t...__.”title”ᐳ
ᐳSingleTableTopic
ᐳSingleTablePost
ᐳSingleTableDivider
ᐳSingleTableChecklist
ᐳSingleTableChecklistItem"}}:::plan + PgClassExpression384 o--o PgClassExpression385 %% define steps classDef bucket0 stroke:#696969 - class Bucket0,__Value2,PgSelect8,Access9,Access10,Object11,Connection12,Lambda15,Access16,PgSelect18,First20,PgSelectRows21,PgSelectSingle22,Lambda24,ConnectionItems271,PgSelectInlineApply376,Access377,PgSelectInlineApply380,Access381 bucket0 + class Bucket0,__Value2,PgSelect8,Access9,Access10,Object11,Connection12,Lambda15,Access16,PgSelect18,First20,PgSelectRows21,PgSelectSingle22,Lambda24,ConnectionItems281,PgSelectInlineApply386,Access387,PgSelectInlineApply390,Access391 bucket0 classDef bucket1 stroke:#00bfff class Bucket1 bucket1 classDef bucket2 stroke:#7f007f - class Bucket2,PgClassExpression274,List276,Lambda277,PgClassExpression278,PgClassExpression279,First284,PgSelectRows285,PgSelectSingle286,List382,Lambda383 bucket2 + class Bucket2,PgClassExpression284,List286,Lambda287,PgClassExpression288,PgClassExpression289,First294,PgSelectRows295,PgSelectSingle296,List392,Lambda393 bucket2 classDef bucket3 stroke:#ffa500 - class Bucket3,Access388,Access389 bucket3 + class Bucket3,Access398,Access399 bucket3 classDef bucket4 stroke:#0000ff - class Bucket4,PgSelect29,First33,PgSelectRows34,PgSelectSingle35,PgClassExpression287,List288,Lambda289,PgClassExpression290,PgClassExpression291,First296,PgSelectRows297,PgSelectSingle298,PgSelectInlineApply384,Access385,List386,Lambda387 bucket4 + class Bucket4,PgSelect29,First33,PgSelectRows34,PgSelectSingle35,PgClassExpression297,List298,Lambda299,PgClassExpression300,PgClassExpression301,First306,PgSelectRows307,PgSelectSingle308,PgSelectInlineApply394,Access395,List396,Lambda397 bucket4 classDef bucket5 stroke:#7fff00 class Bucket5,PgSelect39,First43,PgSelectRows44,PgSelectSingle45 bucket5 classDef bucket6 stroke:#ff1493 @@ -383,14 +392,16 @@ graph TD class Bucket22,PgSelect254,First258,PgSelectRows259,PgSelectSingle260 bucket22 classDef bucket23 stroke:#ff1493 class Bucket23,PgSelect264,First268,PgSelectRows269,PgSelectSingle270 bucket23 - classDef bucket25 stroke:#dda0dd - class Bucket25,PgClassExpression301,PgClassExpression302 bucket25 + classDef bucket24 stroke:#808000 + class Bucket24,PgSelect274,First278,PgSelectRows279,PgSelectSingle280 bucket24 classDef bucket26 stroke:#ff0000 - class Bucket26,__Item299,PgSelectSingle300,PgClassExpression303,PgClassExpression306,Lambda307,PgClassExpression334,First343,PgSelectRows344,PgSelectSingle345,List378,Lambda379 bucket26 + class Bucket26,PgClassExpression311,PgClassExpression312 bucket26 classDef bucket27 stroke:#ffff00 - class Bucket27,PgClassExpression308,PgClassExpression309 bucket27 + class Bucket27,__Item309,PgSelectSingle310,PgClassExpression313,PgClassExpression316,Lambda317,PgClassExpression344,First353,PgSelectRows354,PgSelectSingle355,List388,Lambda389 bucket27 classDef bucket28 stroke:#00ffff - class Bucket28,List316,Lambda317,List319,Lambda320,List321,Lambda322,List324,Lambda325,List327,Lambda328 bucket28 + class Bucket28,PgClassExpression318,PgClassExpression319 bucket28 classDef bucket29 stroke:#4169e1 - class Bucket29,PgClassExpression374,PgClassExpression375 bucket29 + class Bucket29,List326,Lambda327,List329,Lambda330,List331,Lambda332,List334,Lambda335,List337,Lambda338 bucket29 + classDef bucket30 stroke:#3cb371 + class Bucket30,PgClassExpression384,PgClassExpression385 bucket30 diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs index a7ee0453a2..15a634693a 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs @@ -74,6 +74,35 @@ const awsApplicationThirdPartyVulnerabilitiesCodec = recordCodec({ }, executor: executor }); +const foreignKeyReturnTypeTestsIdentifier = sql.identifier("polymorphic", "foreign_key_return_type_tests"); +const foreignKeyReturnTypeTestsCodec = recordCodec({ + name: "foreignKeyReturnTypeTests", + identifier: foreignKeyReturnTypeTestsIdentifier, + attributes: { + __proto__: null, + id: { + codec: TYPES.int, + notNull: true, + hasDefault: true + }, + topic_id: { + codec: TYPES.int + } + }, + extensions: { + isTableLike: true, + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "foreign_key_return_type_tests" + }, + tags: { + __proto__: null, + behavior: "-insert -update -delete -filter -filterBy -order -orderBy" + } + }, + executor: executor +}); const gcpApplicationFirstPartyVulnerabilitiesIdentifier = sql.identifier("polymorphic", "gcp_application_first_party_vulnerabilities"); const gcpApplicationFirstPartyVulnerabilitiesCodec = recordCodec({ name: "gcpApplicationFirstPartyVulnerabilities", @@ -2234,6 +2263,28 @@ const aws_application_third_party_vulnerabilities_resourceOptionsConfig = { isPrimary: true }] }; +const foreign_key_return_type_testsUniques = [{ + attributes: ["id"], + isPrimary: true +}]; +const foreign_key_return_type_tests_resourceOptionsConfig = { + executor: executor, + name: "foreign_key_return_type_tests", + identifier: "main.polymorphic.foreign_key_return_type_tests", + from: foreignKeyReturnTypeTestsIdentifier, + codec: foreignKeyReturnTypeTestsCodec, + extensions: { + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "foreign_key_return_type_tests" + }, + tags: { + behavior: "-insert -update -delete -filter -filterBy -order -orderBy" + } + }, + uniques: foreign_key_return_type_testsUniques +}; const gcp_application_first_party_vulnerabilities_resourceOptionsConfig = { executor: executor, name: "gcp_application_first_party_vulnerabilities", @@ -2744,6 +2795,7 @@ const registryConfig = { awsApplicationFirstPartyVulnerabilities: awsApplicationFirstPartyVulnerabilitiesCodec, int4: TYPES.int, awsApplicationThirdPartyVulnerabilities: awsApplicationThirdPartyVulnerabilitiesCodec, + foreignKeyReturnTypeTests: foreignKeyReturnTypeTestsCodec, gcpApplicationFirstPartyVulnerabilities: gcpApplicationFirstPartyVulnerabilitiesCodec, gcpApplicationThirdPartyVulnerabilities: gcpApplicationThirdPartyVulnerabilitiesCodec, organizations: organizationsCodec, @@ -3104,6 +3156,7 @@ const registryConfig = { __proto__: null, aws_application_first_party_vulnerabilities: aws_application_first_party_vulnerabilities_resourceOptionsConfig, aws_application_third_party_vulnerabilities: aws_application_third_party_vulnerabilities_resourceOptionsConfig, + foreign_key_return_type_tests: foreign_key_return_type_tests_resourceOptionsConfig, gcp_application_first_party_vulnerabilities: gcp_application_first_party_vulnerabilities_resourceOptionsConfig, gcp_application_third_party_vulnerabilities: gcp_application_third_party_vulnerabilities_resourceOptionsConfig, organizations: organizations_resourceOptionsConfig, @@ -3515,6 +3568,23 @@ const registryConfig = { isReferencee: true } }, + foreignKeyReturnTypeTests: { + __proto__: null, + topicByReturnType: { + localCodec: foreignKeyReturnTypeTestsCodec, + remoteResourceOptions: single_table_items_resourceOptionsConfig, + localAttributes: ["topic_id"], + remoteAttributes: ["id"], + isUnique: true, + extensions: { + tags: { + behavior: ["-manyRelation:resource:list -manyRelation:resource:connection"], + fieldName: "topicByReturnType", + returnType: "SingleTableTopic" + } + } + } + }, gcpApplicationFirstPartyVulnerabilities: { __proto__: null, firstPartyVulnerabilitiesByMyFirstPartyVulnerabilityId: { @@ -3948,6 +4018,20 @@ const registryConfig = { } } }, + foreignKeyReturnTypeTestsByTheirTopicId: { + localCodec: singleTableItemsCodec, + remoteResourceOptions: foreign_key_return_type_tests_resourceOptionsConfig, + localAttributes: ["id"], + remoteAttributes: ["topic_id"], + isReferencee: true, + extensions: { + tags: { + behavior: ["-manyRelation:resource:list -manyRelation:resource:connection"], + fieldName: "topicByReturnType", + returnType: "SingleTableTopic" + } + } + }, singleTableItemRelationsByTheirChildId: { localCodec: singleTableItemsCodec, remoteResourceOptions: single_table_item_relations_resourceOptionsConfig, @@ -4840,6 +4924,7 @@ const Collection_typeNameFromType = ((interfaceTypeName, polymorphism) => { typeNameFromType.displayName = `${interfaceTypeName}_typeNameFromType`; return typeNameFromType; })("Collection", spec_collections.polymorphism); +const resource_foreign_key_return_type_testsPgResource = registry.pgResources["foreign_key_return_type_tests"]; const argDetailsSimple_relational_topic_by_id_fn = [{ graphqlArgName: "id", pgCodec: TYPES.int, @@ -9079,6 +9164,9 @@ type Query { """ query: Query! + """Get a single \`ForeignKeyReturnTypeTest\`.""" + foreignKeyReturnTypeTestById(id: Int!): ForeignKeyReturnTypeTest + """Get a single \`Organization\`.""" organizationByOrganizationId(organizationId: Int!): Organization @@ -9262,6 +9350,29 @@ type Query { orderBy: [ZeroImplementationsOrderBy!] ): ZeroImplementationsConnection + """ + Reads and enables pagination through a set of \`ForeignKeyReturnTypeTest\`. + """ + allForeignKeyReturnTypeTests( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): ForeignKeyReturnTypeTestsConnection + """Reads and enables pagination through a set of \`Organization\`.""" allOrganizations( """Only read the first \`n\` values of the set.""" @@ -9729,6 +9840,16 @@ type Query { ): CollectionsConnection } +type ForeignKeyReturnTypeTest { + id: Int! + topicId: Int + + """ + Reads a single \`SingleTableTopic\` that is related to this \`ForeignKeyReturnTypeTest\`. + """ + topicByReturnType: SingleTableTopic +} + """ A condition to be used against \`Vulnerability\` object types. All fields are tested for equality and combined with a logical ‘and.’ @@ -9809,6 +9930,34 @@ enum ZeroImplementationsOrderBy { NAME_DESC } +"""A connection to a list of \`ForeignKeyReturnTypeTest\` values.""" +type ForeignKeyReturnTypeTestsConnection { + """A list of \`ForeignKeyReturnTypeTest\` objects.""" + nodes: [ForeignKeyReturnTypeTest]! + + """ + A list of edges which contains the \`ForeignKeyReturnTypeTest\` and cursor to aid in pagination. + """ + edges: [ForeignKeyReturnTypeTestsEdge]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* \`ForeignKeyReturnTypeTest\` you could get from the connection. + """ + totalCount: Int! +} + +"""A \`ForeignKeyReturnTypeTest\` edge in the connection.""" +type ForeignKeyReturnTypeTestsEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The \`ForeignKeyReturnTypeTest\` at the end of the edge.""" + node: ForeignKeyReturnTypeTest +} + """A connection to a list of \`Organization\` values.""" type OrganizationsConnection { """A list of \`Organization\` objects.""" @@ -11233,6 +11382,18 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + allForeignKeyReturnTypeTests: { + plan() { + return connection(resource_foreign_key_return_type_testsPgResource.find()); + }, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, allLogEntries: { plan() { return connection(otherSource_log_entriesPgResource.find()); @@ -11508,6 +11669,13 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + foreignKeyReturnTypeTestById(_$root, { + $id + }) { + return resource_foreign_key_return_type_testsPgResource.get({ + id: $id + }); + }, getSingleTableTopicById($root, args, _info) { const selectArgs = makeArgs_get_single_table_topic_by_id(args); return resource_get_single_table_topic_by_idPgResource.execute(selectArgs); @@ -11811,6 +11979,32 @@ export const objects = { return resourceByTypeName_FirstPartyVulnerability_first_party_vulnerabilitiesPgResource.get(spec); } }, + ForeignKeyReturnTypeTest: { + assertStep: assertPgClassSingleStep, + plans: { + topicByReturnType($record) { + return otherSource_single_table_itemsPgResource.get({ + id: $record.get("topic_id") + }); + }, + topicId($record) { + return $record.get("topic_id"); + } + }, + planType($specifier) { + const spec = Object.create(null); + for (const pkCol of foreign_key_return_type_testsUniques[0].attributes) { + spec[pkCol] = get2($specifier, pkCol); + } + return resource_foreign_key_return_type_testsPgResource.get(spec); + } + }, + ForeignKeyReturnTypeTestsConnection: { + assertStep: ConnectionStep, + plans: { + totalCount: totalCountConnectionPlan + } + }, GcpApplication: { assertStep: assertPgClassSingleStep, plans: { diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql index 2204639388..ac3eb0ca64 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql @@ -883,6 +883,44 @@ type FirstPartyVulnerability implements Vulnerability { teamName: String } +type ForeignKeyReturnTypeTest { + id: Int! + + """ + Reads a single `SingleTableTopic` that is related to this `ForeignKeyReturnTypeTest`. + """ + topicByReturnType: SingleTableTopic + topicId: Int +} + +"""A connection to a list of `ForeignKeyReturnTypeTest` values.""" +type ForeignKeyReturnTypeTestsConnection { + """ + A list of edges which contains the `ForeignKeyReturnTypeTest` and cursor to aid in pagination. + """ + edges: [ForeignKeyReturnTypeTestsEdge]! + + """A list of `ForeignKeyReturnTypeTest` objects.""" + nodes: [ForeignKeyReturnTypeTest]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* `ForeignKeyReturnTypeTest` you could get from the connection. + """ + totalCount: Int! +} + +"""A `ForeignKeyReturnTypeTest` edge in the connection.""" +type ForeignKeyReturnTypeTestsEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The `ForeignKeyReturnTypeTest` at the end of the edge.""" + node: ForeignKeyReturnTypeTest +} + type GcpApplication implements Application { gcpId: String id: Int! @@ -1550,6 +1588,29 @@ type Query { orderBy: [CollectionsOrderBy!] = [PRIMARY_KEY_ASC] ): CollectionsConnection + """ + Reads and enables pagination through a set of `ForeignKeyReturnTypeTest`. + """ + allForeignKeyReturnTypeTests( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): ForeignKeyReturnTypeTestsConnection + """Reads and enables pagination through a set of `LogEntry`.""" allLogEntries( """Read all values in the set after (below) this cursor.""" @@ -2085,6 +2146,9 @@ type Query { """The method to use when ordering `ZeroImplementation`.""" orderBy: [ZeroImplementationsOrderBy!] ): ZeroImplementationsConnection + + """Get a single `ForeignKeyReturnTypeTest`.""" + foreignKeyReturnTypeTestById(id: Int!): ForeignKeyReturnTypeTest getSingleTableTopicById(id: Int): SingleTableTopic """Get a single `LogEntry`.""" diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs index a7792f2a3f..4316b4ad0c 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs @@ -87,6 +87,35 @@ const awsApplicationThirdPartyVulnerabilitiesCodec = recordCodec({ }, executor: executor }); +const foreignKeyReturnTypeTestsIdentifier = sql.identifier("polymorphic", "foreign_key_return_type_tests"); +const foreignKeyReturnTypeTestsCodec = recordCodec({ + name: "foreignKeyReturnTypeTests", + identifier: foreignKeyReturnTypeTestsIdentifier, + attributes: { + __proto__: null, + id: { + codec: TYPES.int, + notNull: true, + hasDefault: true + }, + topic_id: { + codec: TYPES.int + } + }, + extensions: { + isTableLike: true, + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "foreign_key_return_type_tests" + }, + tags: { + __proto__: null, + behavior: "-insert -update -delete -filter -filterBy -order -orderBy" + } + }, + executor: executor +}); const gcpApplicationFirstPartyVulnerabilitiesIdentifier = sql.identifier("polymorphic", "gcp_application_first_party_vulnerabilities"); const gcpApplicationFirstPartyVulnerabilitiesCodec = recordCodec({ name: "gcpApplicationFirstPartyVulnerabilities", @@ -2247,6 +2276,28 @@ const aws_application_third_party_vulnerabilities_resourceOptionsConfig = { isPrimary: true }] }; +const foreign_key_return_type_testsUniques = [{ + attributes: ["id"], + isPrimary: true +}]; +const foreign_key_return_type_tests_resourceOptionsConfig = { + executor: executor, + name: "foreign_key_return_type_tests", + identifier: "main.polymorphic.foreign_key_return_type_tests", + from: foreignKeyReturnTypeTestsIdentifier, + codec: foreignKeyReturnTypeTestsCodec, + extensions: { + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "foreign_key_return_type_tests" + }, + tags: { + behavior: "-insert -update -delete -filter -filterBy -order -orderBy" + } + }, + uniques: foreign_key_return_type_testsUniques +}; const gcp_application_first_party_vulnerabilities_resourceOptionsConfig = { executor: executor, name: "gcp_application_first_party_vulnerabilities", @@ -2757,6 +2808,7 @@ const registryConfig = { awsApplicationFirstPartyVulnerabilities: awsApplicationFirstPartyVulnerabilitiesCodec, int4: TYPES.int, awsApplicationThirdPartyVulnerabilities: awsApplicationThirdPartyVulnerabilitiesCodec, + foreignKeyReturnTypeTests: foreignKeyReturnTypeTestsCodec, gcpApplicationFirstPartyVulnerabilities: gcpApplicationFirstPartyVulnerabilitiesCodec, gcpApplicationThirdPartyVulnerabilities: gcpApplicationThirdPartyVulnerabilitiesCodec, organizations: organizationsCodec, @@ -3117,6 +3169,7 @@ const registryConfig = { __proto__: null, aws_application_first_party_vulnerabilities: aws_application_first_party_vulnerabilities_resourceOptionsConfig, aws_application_third_party_vulnerabilities: aws_application_third_party_vulnerabilities_resourceOptionsConfig, + foreign_key_return_type_tests: foreign_key_return_type_tests_resourceOptionsConfig, gcp_application_first_party_vulnerabilities: gcp_application_first_party_vulnerabilities_resourceOptionsConfig, gcp_application_third_party_vulnerabilities: gcp_application_third_party_vulnerabilities_resourceOptionsConfig, organizations: organizations_resourceOptionsConfig, @@ -3528,6 +3581,23 @@ const registryConfig = { isReferencee: true } }, + foreignKeyReturnTypeTests: { + __proto__: null, + topicByReturnType: { + localCodec: foreignKeyReturnTypeTestsCodec, + remoteResourceOptions: single_table_items_resourceOptionsConfig, + localAttributes: ["topic_id"], + remoteAttributes: ["id"], + isUnique: true, + extensions: { + tags: { + behavior: ["-manyRelation:resource:list -manyRelation:resource:connection"], + fieldName: "topicByReturnType", + returnType: "SingleTableTopic" + } + } + } + }, gcpApplicationFirstPartyVulnerabilities: { __proto__: null, firstPartyVulnerabilitiesByMyFirstPartyVulnerabilityId: { @@ -3961,6 +4031,20 @@ const registryConfig = { } } }, + foreignKeyReturnTypeTestsByTheirTopicId: { + localCodec: singleTableItemsCodec, + remoteResourceOptions: foreign_key_return_type_tests_resourceOptionsConfig, + localAttributes: ["id"], + remoteAttributes: ["topic_id"], + isReferencee: true, + extensions: { + tags: { + behavior: ["-manyRelation:resource:list -manyRelation:resource:connection"], + fieldName: "topicByReturnType", + returnType: "SingleTableTopic" + } + } + }, singleTableItemRelationsByTheirChildId: { localCodec: singleTableItemsCodec, remoteResourceOptions: single_table_item_relations_resourceOptionsConfig, @@ -4247,6 +4331,14 @@ const makeTableNodeIdHandler = ({ deprecationReason }; }; +const spec_resource_foreign_key_return_type_testsPgResource = registry.pgResources["foreign_key_return_type_tests"]; +const nodeIdHandler_ForeignKeyReturnTypeTest = makeTableNodeIdHandler({ + typeName: "ForeignKeyReturnTypeTest", + identifier: "foreign_key_return_type_tests", + nodeIdCodec: base64JSONNodeIdCodec, + resource: spec_resource_foreign_key_return_type_testsPgResource, + pk: foreign_key_return_type_testsUniques[0].attributes +}); const spec_resource_organizationsPgResource = registry.pgResources["organizations"]; const nodeIdHandler_Organization = makeTableNodeIdHandler({ typeName: "Organization", @@ -4480,6 +4572,7 @@ const nodeIdHandlerByTypeName = { return obj[0] === "SeriesCollection"; } }, + ForeignKeyReturnTypeTest: nodeIdHandler_ForeignKeyReturnTypeTest, Organization: nodeIdHandler_Organization, Person: nodeIdHandler_Person, Priority: nodeIdHandler_Priority, @@ -5508,6 +5601,10 @@ const nodeFetcher_SeriesCollection = $nodeId => { const $decoded = lambda($nodeId, specForHandler(nodeIdHandlerByTypeName.SeriesCollection)); return nodeIdHandlerByTypeName.SeriesCollection.get(nodeIdHandlerByTypeName.SeriesCollection.getSpec($decoded)); }; +const nodeFetcher_ForeignKeyReturnTypeTest = $nodeId => { + const $decoded = lambda($nodeId, specForHandler(nodeIdHandler_ForeignKeyReturnTypeTest)); + return nodeIdHandler_ForeignKeyReturnTypeTest.get(nodeIdHandler_ForeignKeyReturnTypeTest.getSpec($decoded)); +}; const nodeFetcher_Organization = $nodeId => { const $decoded = lambda($nodeId, specForHandler(nodeIdHandler_Organization)); return nodeIdHandler_Organization.get(nodeIdHandler_Organization.getSpec($decoded)); @@ -10317,6 +10414,9 @@ type Query implements Node { nodeId: ID! ): Node + """Get a single \`ForeignKeyReturnTypeTest\`.""" + foreignKeyReturnTypeTestById(id: Int!): ForeignKeyReturnTypeTest + """Get a single \`Organization\`.""" organizationByOrganizationId(organizationId: Int!): Organization @@ -10483,6 +10583,16 @@ type Query implements Node { nodeId: ID! ): SeriesCollection + """ + Reads a single \`ForeignKeyReturnTypeTest\` using its globally unique \`ID\`. + """ + foreignKeyReturnTypeTest( + """ + The globally unique \`ID\` to be used in selecting a single \`ForeignKeyReturnTypeTest\`. + """ + nodeId: ID! + ): ForeignKeyReturnTypeTest + """Reads a single \`Organization\` using its globally unique \`ID\`.""" organization( """ @@ -10714,6 +10824,29 @@ type Query implements Node { orderBy: [ZeroImplementationsOrderBy!] ): ZeroImplementationsConnection + """ + Reads and enables pagination through a set of \`ForeignKeyReturnTypeTest\`. + """ + allForeignKeyReturnTypeTests( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): ForeignKeyReturnTypeTestsConnection + """Reads and enables pagination through a set of \`Organization\`.""" allOrganizations( """Only read the first \`n\` values of the set.""" @@ -11301,6 +11434,20 @@ type Query implements Node { ): CollectionsConnection } +type ForeignKeyReturnTypeTest implements Node { + """ + A globally unique identifier. Can be used in various places throughout the system to identify this single value. + """ + nodeId: ID! + id: Int! + topicId: Int + + """ + Reads a single \`SingleTableTopic\` that is related to this \`ForeignKeyReturnTypeTest\`. + """ + topicByReturnType: SingleTableTopic +} + type FirstPartyVulnerability implements Node & Vulnerability { """ A globally unique identifier. Can be used in various places throughout the system to identify this single value. @@ -11453,6 +11600,34 @@ enum ZeroImplementationsOrderBy { NAME_DESC } +"""A connection to a list of \`ForeignKeyReturnTypeTest\` values.""" +type ForeignKeyReturnTypeTestsConnection { + """A list of \`ForeignKeyReturnTypeTest\` objects.""" + nodes: [ForeignKeyReturnTypeTest]! + + """ + A list of edges which contains the \`ForeignKeyReturnTypeTest\` and cursor to aid in pagination. + """ + edges: [ForeignKeyReturnTypeTestsEdge]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* \`ForeignKeyReturnTypeTest\` you could get from the connection. + """ + totalCount: Int! +} + +"""A \`ForeignKeyReturnTypeTest\` edge in the connection.""" +type ForeignKeyReturnTypeTestsEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The \`ForeignKeyReturnTypeTest\` at the end of the edge.""" + node: ForeignKeyReturnTypeTest +} + """A connection to a list of \`Organization\` values.""" type OrganizationsConnection { """A list of \`Organization\` objects.""" @@ -15496,6 +15671,18 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + allForeignKeyReturnTypeTests: { + plan() { + return connection(spec_resource_foreign_key_return_type_testsPgResource.find()); + }, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, allGcpApplications: { plan() { return connection(spec_resource_gcp_applicationsPgResource.find()); @@ -15821,6 +16008,17 @@ export const objects = { id: $id }); }, + foreignKeyReturnTypeTest(_$parent, args) { + const $nodeId = args.getRaw("nodeId"); + return nodeFetcher_ForeignKeyReturnTypeTest($nodeId); + }, + foreignKeyReturnTypeTestById(_$root, { + $id + }) { + return spec_resource_foreign_key_return_type_testsPgResource.get({ + id: $id + }); + }, gcpApplication(_$parent, args) { const $nodeId = args.getRaw("nodeId"); return nodeFetcher_GcpApplication($nodeId); @@ -17391,6 +17589,36 @@ export const objects = { return spec_resource_first_party_vulnerabilitiesPgResource.get(spec); } }, + ForeignKeyReturnTypeTest: { + assertStep: assertPgClassSingleStep, + plans: { + nodeId($parent) { + const specifier = nodeIdHandler_ForeignKeyReturnTypeTest.plan($parent); + return lambda(specifier, nodeIdCodecs[nodeIdHandler_ForeignKeyReturnTypeTest.codec.name].encode); + }, + topicByReturnType($record) { + return resource_single_table_itemsPgResource.get({ + id: $record.get("topic_id") + }); + }, + topicId($record) { + return $record.get("topic_id"); + } + }, + planType($specifier) { + const spec = Object.create(null); + for (const pkCol of foreign_key_return_type_testsUniques[0].attributes) { + spec[pkCol] = get2($specifier, pkCol); + } + return spec_resource_foreign_key_return_type_testsPgResource.get(spec); + } + }, + ForeignKeyReturnTypeTestsConnection: { + assertStep: ConnectionStep, + plans: { + totalCount: totalCountConnectionPlan + } + }, GcpApplication: { assertStep: assertPgClassSingleStep, plans: { diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql index 22ed5d8894..73e94d9b7f 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql @@ -2218,6 +2218,49 @@ input FirstPartyVulnerabilityPatch { teamName: String } +type ForeignKeyReturnTypeTest implements Node { + id: Int! + + """ + A globally unique identifier. Can be used in various places throughout the system to identify this single value. + """ + nodeId: ID! + + """ + Reads a single `SingleTableTopic` that is related to this `ForeignKeyReturnTypeTest`. + """ + topicByReturnType: SingleTableTopic + topicId: Int +} + +"""A connection to a list of `ForeignKeyReturnTypeTest` values.""" +type ForeignKeyReturnTypeTestsConnection { + """ + A list of edges which contains the `ForeignKeyReturnTypeTest` and cursor to aid in pagination. + """ + edges: [ForeignKeyReturnTypeTestsEdge]! + + """A list of `ForeignKeyReturnTypeTest` objects.""" + nodes: [ForeignKeyReturnTypeTest]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* `ForeignKeyReturnTypeTest` you could get from the connection. + """ + totalCount: Int! +} + +"""A `ForeignKeyReturnTypeTest` edge in the connection.""" +type ForeignKeyReturnTypeTestsEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The `ForeignKeyReturnTypeTest` at the end of the edge.""" + node: ForeignKeyReturnTypeTest +} + type GcpApplication implements Application & Node { gcpId: String id: Int! @@ -3801,6 +3844,29 @@ type Query implements Node { orderBy: [FirstPartyVulnerabilitiesOrderBy!] = [PRIMARY_KEY_ASC] ): FirstPartyVulnerabilitiesConnection + """ + Reads and enables pagination through a set of `ForeignKeyReturnTypeTest`. + """ + allForeignKeyReturnTypeTests( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): ForeignKeyReturnTypeTestsConnection + """Reads and enables pagination through a set of `GcpApplication`.""" allGcpApplications( """Read all values in the set after (below) this cursor.""" @@ -4421,6 +4487,19 @@ type Query implements Node { """Get a single `FirstPartyVulnerability`.""" firstPartyVulnerabilityById(id: Int!): FirstPartyVulnerability + """ + Reads a single `ForeignKeyReturnTypeTest` using its globally unique `ID`. + """ + foreignKeyReturnTypeTest( + """ + The globally unique `ID` to be used in selecting a single `ForeignKeyReturnTypeTest`. + """ + nodeId: ID! + ): ForeignKeyReturnTypeTest + + """Get a single `ForeignKeyReturnTypeTest`.""" + foreignKeyReturnTypeTestById(id: Int!): ForeignKeyReturnTypeTest + """Reads a single `GcpApplication` using its globally unique `ID`.""" gcpApplication( """ diff --git a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs index a0603c9e1c..ab485c3b3d 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs @@ -74,6 +74,35 @@ const awsApplicationThirdPartyVulnerabilitiesCodec = recordCodec({ }, executor: executor }); +const foreignKeyReturnTypeTestsIdentifier = sql.identifier("polymorphic", "foreign_key_return_type_tests"); +const foreignKeyReturnTypeTestsCodec = recordCodec({ + name: "foreignKeyReturnTypeTests", + identifier: foreignKeyReturnTypeTestsIdentifier, + attributes: { + __proto__: null, + id: { + codec: TYPES.int, + notNull: true, + hasDefault: true + }, + topic_id: { + codec: TYPES.int + } + }, + extensions: { + isTableLike: true, + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "foreign_key_return_type_tests" + }, + tags: { + __proto__: null, + behavior: "-insert -update -delete -filter -filterBy -order -orderBy" + } + }, + executor: executor +}); const gcpApplicationFirstPartyVulnerabilitiesIdentifier = sql.identifier("polymorphic", "gcp_application_first_party_vulnerabilities"); const gcpApplicationFirstPartyVulnerabilitiesCodec = recordCodec({ name: "gcpApplicationFirstPartyVulnerabilities", @@ -2234,6 +2263,28 @@ const aws_application_third_party_vulnerabilities_resourceOptionsConfig = { isPrimary: true }] }; +const foreign_key_return_type_testsUniques = [{ + attributes: ["id"], + isPrimary: true +}]; +const foreign_key_return_type_tests_resourceOptionsConfig = { + executor: executor, + name: "foreign_key_return_type_tests", + identifier: "main.polymorphic.foreign_key_return_type_tests", + from: foreignKeyReturnTypeTestsIdentifier, + codec: foreignKeyReturnTypeTestsCodec, + extensions: { + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "foreign_key_return_type_tests" + }, + tags: { + behavior: "-insert -update -delete -filter -filterBy -order -orderBy" + } + }, + uniques: foreign_key_return_type_testsUniques +}; const gcp_application_first_party_vulnerabilities_resourceOptionsConfig = { executor: executor, name: "gcp_application_first_party_vulnerabilities", @@ -2744,6 +2795,7 @@ const registryConfig = { awsApplicationFirstPartyVulnerabilities: awsApplicationFirstPartyVulnerabilitiesCodec, int4: TYPES.int, awsApplicationThirdPartyVulnerabilities: awsApplicationThirdPartyVulnerabilitiesCodec, + foreignKeyReturnTypeTests: foreignKeyReturnTypeTestsCodec, gcpApplicationFirstPartyVulnerabilities: gcpApplicationFirstPartyVulnerabilitiesCodec, gcpApplicationThirdPartyVulnerabilities: gcpApplicationThirdPartyVulnerabilitiesCodec, organizations: organizationsCodec, @@ -3104,6 +3156,7 @@ const registryConfig = { __proto__: null, aws_application_first_party_vulnerabilities: aws_application_first_party_vulnerabilities_resourceOptionsConfig, aws_application_third_party_vulnerabilities: aws_application_third_party_vulnerabilities_resourceOptionsConfig, + foreign_key_return_type_tests: foreign_key_return_type_tests_resourceOptionsConfig, gcp_application_first_party_vulnerabilities: gcp_application_first_party_vulnerabilities_resourceOptionsConfig, gcp_application_third_party_vulnerabilities: gcp_application_third_party_vulnerabilities_resourceOptionsConfig, organizations: organizations_resourceOptionsConfig, @@ -3515,6 +3568,23 @@ const registryConfig = { isReferencee: true } }, + foreignKeyReturnTypeTests: { + __proto__: null, + topicByReturnType: { + localCodec: foreignKeyReturnTypeTestsCodec, + remoteResourceOptions: single_table_items_resourceOptionsConfig, + localAttributes: ["topic_id"], + remoteAttributes: ["id"], + isUnique: true, + extensions: { + tags: { + behavior: ["-manyRelation:resource:list -manyRelation:resource:connection"], + fieldName: "topicByReturnType", + returnType: "SingleTableTopic" + } + } + } + }, gcpApplicationFirstPartyVulnerabilities: { __proto__: null, firstPartyVulnerabilitiesByMyFirstPartyVulnerabilityId: { @@ -3948,6 +4018,20 @@ const registryConfig = { } } }, + foreignKeyReturnTypeTestsByTheirTopicId: { + localCodec: singleTableItemsCodec, + remoteResourceOptions: foreign_key_return_type_tests_resourceOptionsConfig, + localAttributes: ["id"], + remoteAttributes: ["topic_id"], + isReferencee: true, + extensions: { + tags: { + behavior: ["-manyRelation:resource:list -manyRelation:resource:connection"], + fieldName: "topicByReturnType", + returnType: "SingleTableTopic" + } + } + }, singleTableItemRelationsByTheirChildId: { localCodec: singleTableItemsCodec, remoteResourceOptions: single_table_item_relations_resourceOptionsConfig, @@ -5079,6 +5163,7 @@ const Collection_typeNameFromType = ((interfaceTypeName, polymorphism) => { typeNameFromType.displayName = `${interfaceTypeName}_typeNameFromType`; return typeNameFromType; })("Collection", spec_collections.polymorphism); +const resource_foreign_key_return_type_testsPgResource = registry.pgResources["foreign_key_return_type_tests"]; const argDetailsSimple_relational_topic_by_id_fn = [{ graphqlArgName: "id", pgCodec: TYPES.int, @@ -9636,6 +9721,9 @@ type Query { """ query: Query! + """Get a single \`ForeignKeyReturnTypeTest\`.""" + foreignKeyReturnTypeTestById(id: Int!): ForeignKeyReturnTypeTest + """Get a single \`Organization\`.""" organizationByOrganizationId(organizationId: Int!): Organization @@ -9831,6 +9919,29 @@ type Query { orderBy: [ZeroImplementationsOrderBy!] ): ZeroImplementationsConnection + """ + Reads and enables pagination through a set of \`ForeignKeyReturnTypeTest\`. + """ + allForeignKeyReturnTypeTests( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): ForeignKeyReturnTypeTestsConnection + """Reads and enables pagination through a set of \`Organization\`.""" allOrganizations( """Only read the first \`n\` values of the set.""" @@ -10418,6 +10529,16 @@ type Query { ): CollectionsConnection } +type ForeignKeyReturnTypeTest { + id: Int! + topicId: Int + + """ + Reads a single \`SingleTableTopic\` that is related to this \`ForeignKeyReturnTypeTest\`. + """ + topicByReturnType: SingleTableTopic +} + type FirstPartyVulnerability implements Vulnerability { cvssScoreInt: Int id: Int! @@ -10558,6 +10679,34 @@ enum ZeroImplementationsOrderBy { NAME_DESC } +"""A connection to a list of \`ForeignKeyReturnTypeTest\` values.""" +type ForeignKeyReturnTypeTestsConnection { + """A list of \`ForeignKeyReturnTypeTest\` objects.""" + nodes: [ForeignKeyReturnTypeTest]! + + """ + A list of edges which contains the \`ForeignKeyReturnTypeTest\` and cursor to aid in pagination. + """ + edges: [ForeignKeyReturnTypeTestsEdge]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* \`ForeignKeyReturnTypeTest\` you could get from the connection. + """ + totalCount: Int! +} + +"""A \`ForeignKeyReturnTypeTest\` edge in the connection.""" +type ForeignKeyReturnTypeTestsEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The \`ForeignKeyReturnTypeTest\` at the end of the edge.""" + node: ForeignKeyReturnTypeTest +} + """A connection to a list of \`Organization\` values.""" type OrganizationsConnection { """A list of \`Organization\` objects.""" @@ -13989,6 +14138,18 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + allForeignKeyReturnTypeTests: { + plan() { + return connection(resource_foreign_key_return_type_testsPgResource.find()); + }, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, allGcpApplications: { plan() { return connection(otherSource_gcp_applicationsPgResource.find()); @@ -14306,6 +14467,13 @@ export const objects = { id: $id }); }, + foreignKeyReturnTypeTestById(_$root, { + $id + }) { + return resource_foreign_key_return_type_testsPgResource.get({ + id: $id + }); + }, gcpApplicationById(_$root, { $id }) { @@ -15426,6 +15594,32 @@ export const objects = { return paths_0_resource_first_party_vulnerabilitiesPgResource.get(spec); } }, + ForeignKeyReturnTypeTest: { + assertStep: assertPgClassSingleStep, + plans: { + topicByReturnType($record) { + return otherSource_single_table_itemsPgResource.get({ + id: $record.get("topic_id") + }); + }, + topicId($record) { + return $record.get("topic_id"); + } + }, + planType($specifier) { + const spec = Object.create(null); + for (const pkCol of foreign_key_return_type_testsUniques[0].attributes) { + spec[pkCol] = get2($specifier, pkCol); + } + return resource_foreign_key_return_type_testsPgResource.get(spec); + } + }, + ForeignKeyReturnTypeTestsConnection: { + assertStep: ConnectionStep, + plans: { + totalCount: totalCountConnectionPlan + } + }, GcpApplication: { assertStep: assertPgClassSingleStep, plans: { diff --git a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql index e238384a71..7697d169f8 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql @@ -2007,6 +2007,44 @@ input FirstPartyVulnerabilityPatch { teamName: String } +type ForeignKeyReturnTypeTest { + id: Int! + + """ + Reads a single `SingleTableTopic` that is related to this `ForeignKeyReturnTypeTest`. + """ + topicByReturnType: SingleTableTopic + topicId: Int +} + +"""A connection to a list of `ForeignKeyReturnTypeTest` values.""" +type ForeignKeyReturnTypeTestsConnection { + """ + A list of edges which contains the `ForeignKeyReturnTypeTest` and cursor to aid in pagination. + """ + edges: [ForeignKeyReturnTypeTestsEdge]! + + """A list of `ForeignKeyReturnTypeTest` objects.""" + nodes: [ForeignKeyReturnTypeTest]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* `ForeignKeyReturnTypeTest` you could get from the connection. + """ + totalCount: Int! +} + +"""A `ForeignKeyReturnTypeTest` edge in the connection.""" +type ForeignKeyReturnTypeTestsEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The `ForeignKeyReturnTypeTest` at the end of the edge.""" + node: ForeignKeyReturnTypeTest +} + type GcpApplication implements Application { gcpId: String id: Int! @@ -3340,6 +3378,29 @@ type Query { orderBy: [FirstPartyVulnerabilitiesOrderBy!] = [PRIMARY_KEY_ASC] ): FirstPartyVulnerabilitiesConnection + """ + Reads and enables pagination through a set of `ForeignKeyReturnTypeTest`. + """ + allForeignKeyReturnTypeTests( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): ForeignKeyReturnTypeTestsConnection + """Reads and enables pagination through a set of `GcpApplication`.""" allGcpApplications( """Read all values in the set after (below) this cursor.""" @@ -3942,6 +4003,9 @@ type Query { """Get a single `FirstPartyVulnerability`.""" firstPartyVulnerabilityById(id: Int!): FirstPartyVulnerability + """Get a single `ForeignKeyReturnTypeTest`.""" + foreignKeyReturnTypeTestById(id: Int!): ForeignKeyReturnTypeTest + """Get a single `GcpApplication`.""" gcpApplicationById(id: Int!): GcpApplication getSingleTableTopicById(id: Int): SingleTableTopic diff --git a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs index ef08378c27..8a9e29ce60 100644 --- a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs @@ -72,6 +72,35 @@ const awsApplicationThirdPartyVulnerabilitiesCodec = recordCodec({ }, executor: executor }); +const foreignKeyReturnTypeTestsIdentifier = sql.identifier("polymorphic", "foreign_key_return_type_tests"); +const foreignKeyReturnTypeTestsCodec = recordCodec({ + name: "foreignKeyReturnTypeTests", + identifier: foreignKeyReturnTypeTestsIdentifier, + attributes: { + __proto__: null, + id: { + codec: TYPES.int, + notNull: true, + hasDefault: true + }, + topic_id: { + codec: TYPES.int + } + }, + extensions: { + isTableLike: true, + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "foreign_key_return_type_tests" + }, + tags: { + __proto__: null, + behavior: "-insert -update -delete -filter -filterBy -order -orderBy" + } + }, + executor: executor +}); const gcpApplicationFirstPartyVulnerabilitiesIdentifier = sql.identifier("polymorphic", "gcp_application_first_party_vulnerabilities"); const gcpApplicationFirstPartyVulnerabilitiesCodec = recordCodec({ name: "gcpApplicationFirstPartyVulnerabilities", @@ -2229,6 +2258,28 @@ const aws_application_third_party_vulnerabilities_resourceOptionsConfig = { }, uniques: aws_application_third_party_vulnerabilitiesUniques }; +const foreign_key_return_type_testsUniques = [{ + attributes: ["id"], + isPrimary: true +}]; +const foreign_key_return_type_tests_resourceOptionsConfig = { + executor: executor, + name: "foreign_key_return_type_tests", + identifier: "main.polymorphic.foreign_key_return_type_tests", + from: foreignKeyReturnTypeTestsIdentifier, + codec: foreignKeyReturnTypeTestsCodec, + extensions: { + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "foreign_key_return_type_tests" + }, + tags: { + behavior: "-insert -update -delete -filter -filterBy -order -orderBy" + } + }, + uniques: foreign_key_return_type_testsUniques +}; const gcp_application_first_party_vulnerabilitiesUniques = [{ attributes: ["gcp_application_id", "first_party_vulnerability_id"], isPrimary: true @@ -2738,6 +2789,7 @@ const registryConfig = { awsApplicationFirstPartyVulnerabilities: awsApplicationFirstPartyVulnerabilitiesCodec, int4: TYPES.int, awsApplicationThirdPartyVulnerabilities: awsApplicationThirdPartyVulnerabilitiesCodec, + foreignKeyReturnTypeTests: foreignKeyReturnTypeTestsCodec, gcpApplicationFirstPartyVulnerabilities: gcpApplicationFirstPartyVulnerabilitiesCodec, gcpApplicationThirdPartyVulnerabilities: gcpApplicationThirdPartyVulnerabilitiesCodec, organizations: organizationsCodec, @@ -3098,6 +3150,7 @@ const registryConfig = { __proto__: null, aws_application_first_party_vulnerabilities: aws_application_first_party_vulnerabilities_resourceOptionsConfig, aws_application_third_party_vulnerabilities: aws_application_third_party_vulnerabilities_resourceOptionsConfig, + foreign_key_return_type_tests: foreign_key_return_type_tests_resourceOptionsConfig, gcp_application_first_party_vulnerabilities: gcp_application_first_party_vulnerabilities_resourceOptionsConfig, gcp_application_third_party_vulnerabilities: gcp_application_third_party_vulnerabilities_resourceOptionsConfig, organizations: organizations_resourceOptionsConfig, @@ -3509,6 +3562,23 @@ const registryConfig = { isReferencee: true } }, + foreignKeyReturnTypeTests: { + __proto__: null, + topicByReturnType: { + localCodec: foreignKeyReturnTypeTestsCodec, + remoteResourceOptions: single_table_items_resourceOptionsConfig, + localAttributes: ["topic_id"], + remoteAttributes: ["id"], + isUnique: true, + extensions: { + tags: { + behavior: ["-manyRelation:resource:list -manyRelation:resource:connection"], + fieldName: "topicByReturnType", + returnType: "SingleTableTopic" + } + } + } + }, gcpApplicationFirstPartyVulnerabilities: { __proto__: null, firstPartyVulnerabilitiesByMyFirstPartyVulnerabilityId: { @@ -3942,6 +4012,20 @@ const registryConfig = { } } }, + foreignKeyReturnTypeTestsByTheirTopicId: { + localCodec: singleTableItemsCodec, + remoteResourceOptions: foreign_key_return_type_tests_resourceOptionsConfig, + localAttributes: ["id"], + remoteAttributes: ["topic_id"], + isReferencee: true, + extensions: { + tags: { + behavior: ["-manyRelation:resource:list -manyRelation:resource:connection"], + fieldName: "topicByReturnType", + returnType: "SingleTableTopic" + } + } + }, singleTableItemRelationsByTheirChildId: { localCodec: singleTableItemsCodec, remoteResourceOptions: single_table_item_relations_resourceOptionsConfig, @@ -5520,6 +5604,7 @@ const Collection_typeNameFromType = ((interfaceTypeName, polymorphism) => { return typeNameFromType; })("Collection", spec_collections.polymorphism); const JSONSerialize = value => value; +const resource_foreign_key_return_type_testsPgResource = registry.pgResources["foreign_key_return_type_tests"]; const argDetailsSimple_relational_topic_by_id_fn = [{ graphqlArgName: "id", pgCodec: TYPES.int, @@ -10306,6 +10391,9 @@ type Query { """Get a single \`AwsApplicationThirdPartyVulnerability\`.""" awsApplicationThirdPartyVulnerabilityByAwsApplicationIdAndThirdPartyVulnerabilityId(awsApplicationId: Int!, thirdPartyVulnerabilityId: Int!): AwsApplicationThirdPartyVulnerability + """Get a single \`ForeignKeyReturnTypeTest\`.""" + foreignKeyReturnTypeTestByRowId(rowId: Int!): ForeignKeyReturnTypeTest + """Get a single \`GcpApplicationFirstPartyVulnerability\`.""" gcpApplicationFirstPartyVulnerabilityByGcpApplicationIdAndFirstPartyVulnerabilityId(gcpApplicationId: Int!, firstPartyVulnerabilityId: Int!): GcpApplicationFirstPartyVulnerability @@ -10561,6 +10649,29 @@ type Query { orderBy: [AwsApplicationThirdPartyVulnerabilityOrderBy!] = [PRIMARY_KEY_ASC] ): AwsApplicationThirdPartyVulnerabilityConnection + """ + Reads and enables pagination through a set of \`ForeignKeyReturnTypeTest\`. + """ + allForeignKeyReturnTypeTests( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): ForeignKeyReturnTypeTestConnection + """ Reads and enables pagination through a set of \`GcpApplicationFirstPartyVulnerability\`. """ @@ -11222,6 +11333,16 @@ type Query { ): CollectionConnection } +type ForeignKeyReturnTypeTest { + rowId: Int! + topicId: Int + + """ + Reads a single \`SingleTableTopic\` that is related to this \`ForeignKeyReturnTypeTest\`. + """ + topicByReturnType: SingleTableTopic +} + """A connection to a list of \`ZeroImplementation\` values.""" type ZeroImplementationConnection { """A list of \`ZeroImplementation\` objects.""" @@ -11276,6 +11397,34 @@ enum ZeroImplementationOrderBy { NAME_DESC } +"""A connection to a list of \`ForeignKeyReturnTypeTest\` values.""" +type ForeignKeyReturnTypeTestConnection { + """A list of \`ForeignKeyReturnTypeTest\` objects.""" + nodes: [ForeignKeyReturnTypeTest]! + + """ + A list of edges which contains the \`ForeignKeyReturnTypeTest\` and cursor to aid in pagination. + """ + edges: [ForeignKeyReturnTypeTestEdge]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* \`ForeignKeyReturnTypeTest\` you could get from the connection. + """ + totalCount: Int! +} + +"""A \`ForeignKeyReturnTypeTest\` edge in the connection.""" +type ForeignKeyReturnTypeTestEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The \`ForeignKeyReturnTypeTest\` at the end of the edge.""" + node: ForeignKeyReturnTypeTest +} + """A connection to a list of \`Organization\` values.""" type OrganizationConnection { """A list of \`Organization\` objects.""" @@ -15437,6 +15586,18 @@ export const objects = { orderBy: applyOrderByArgToConnection } }, + allForeignKeyReturnTypeTests: { + plan() { + return connection(resource_foreign_key_return_type_testsPgResource.find()); + }, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, allGcpApplicationFirstPartyVulnerabilities: { plan() { return connection(otherSource_gcp_application_first_party_vulnerabilitiesPgResource.find()); @@ -15798,6 +15959,13 @@ export const objects = { id: $rowId }); }, + foreignKeyReturnTypeTestByRowId(_$root, { + $rowId + }) { + return resource_foreign_key_return_type_testsPgResource.get({ + id: $rowId + }); + }, gcpApplicationByRowId(_$root, { $rowId }) { @@ -17320,6 +17488,33 @@ export const objects = { totalCount: totalCountConnectionPlan } }, + ForeignKeyReturnTypeTest: { + assertStep: assertPgClassSingleStep, + plans: { + rowId: SingleTableTopic_rowIdPlan, + topicByReturnType($record) { + return otherSource_single_table_itemsPgResource.get({ + id: $record.get("topic_id") + }); + }, + topicId($record) { + return $record.get("topic_id"); + } + }, + planType($specifier) { + const spec = Object.create(null); + for (const pkCol of foreign_key_return_type_testsUniques[0].attributes) { + spec[pkCol] = get2($specifier, pkCol); + } + return resource_foreign_key_return_type_testsPgResource.get(spec); + } + }, + ForeignKeyReturnTypeTestConnection: { + assertStep: ConnectionStep, + plans: { + totalCount: totalCountConnectionPlan + } + }, GcpApplication: { assertStep: assertPgClassSingleStep, plans: { diff --git a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql index a9b7e28642..a4f4ecf74f 100644 --- a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql @@ -2613,6 +2613,44 @@ input FirstPartyVulnerabilityPatch { teamName: String } +type ForeignKeyReturnTypeTest { + rowId: Int! + + """ + Reads a single `SingleTableTopic` that is related to this `ForeignKeyReturnTypeTest`. + """ + topicByReturnType: SingleTableTopic + topicId: Int +} + +"""A connection to a list of `ForeignKeyReturnTypeTest` values.""" +type ForeignKeyReturnTypeTestConnection { + """ + A list of edges which contains the `ForeignKeyReturnTypeTest` and cursor to aid in pagination. + """ + edges: [ForeignKeyReturnTypeTestEdge]! + + """A list of `ForeignKeyReturnTypeTest` objects.""" + nodes: [ForeignKeyReturnTypeTest]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* `ForeignKeyReturnTypeTest` you could get from the connection. + """ + totalCount: Int! +} + +"""A `ForeignKeyReturnTypeTest` edge in the connection.""" +type ForeignKeyReturnTypeTestEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The `ForeignKeyReturnTypeTest` at the end of the edge.""" + node: ForeignKeyReturnTypeTest +} + type GcpApplication implements Application { """ Reads and enables pagination through a set of `GcpApplicationFirstPartyVulnerability`. @@ -4420,6 +4458,29 @@ type Query { orderBy: [FirstPartyVulnerabilityOrderBy!] = [PRIMARY_KEY_ASC] ): FirstPartyVulnerabilityConnection + """ + Reads and enables pagination through a set of `ForeignKeyReturnTypeTest`. + """ + allForeignKeyReturnTypeTests( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): ForeignKeyReturnTypeTestConnection + """ Reads and enables pagination through a set of `GcpApplicationFirstPartyVulnerability`. """ @@ -5090,6 +5151,9 @@ type Query { """Get a single `FirstPartyVulnerability`.""" firstPartyVulnerabilityByRowId(rowId: Int!): FirstPartyVulnerability + """Get a single `ForeignKeyReturnTypeTest`.""" + foreignKeyReturnTypeTestByRowId(rowId: Int!): ForeignKeyReturnTypeTest + """Get a single `GcpApplication`.""" gcpApplicationByRowId(rowId: Int!): GcpApplication From 273101bba8a2e3ffbbf2f4337b857e420c960d48 Mon Sep 17 00:00:00 2001 From: tsnobip Date: Mon, 8 Jun 2026 12:15:10 +0200 Subject: [PATCH 3/6] add @foreignReturnType for return type of backward relation --- graphile-build/graphile-build-pg/src/index.ts | 4 + .../src/plugins/PgRelationsPlugin.ts | 12 +- .../__tests__/kitchen-sink-data.sql | 2 +- .../__tests__/kitchen-sink-schema.sql | 3 +- .../return-type-computed-column-setof.json5 | 18 ++ .../polymorphic/return-type-foreign-key.json5 | 35 +-- .../return-type-foreign-key.test.graphql | 31 ++- .../polymorphic-auto-add-types.1.export.mjs | 236 ++++++++++++++++- .../v4/polymorphic-auto-add-types.1.graphql | 154 ++++++++++++ .../schema/v4/polymorphic.1.export.mjs | 238 +++++++++++++++++- .../__tests__/schema/v4/polymorphic.1.graphql | 154 ++++++++++++ .../skipNodePlugin.polymorphic.1.export.mjs | 236 ++++++++++++++++- .../v4/skipNodePlugin.polymorphic.1.graphql | 154 ++++++++++++ .../skipNodePlugin.polymorphic.1.export.mjs | 236 ++++++++++++++++- .../v5/skipNodePlugin.polymorphic.1.graphql | 154 ++++++++++++ .../website/postgraphile/smart-tags.md | 91 ++++++- 16 files changed, 1679 insertions(+), 79 deletions(-) diff --git a/graphile-build/graphile-build-pg/src/index.ts b/graphile-build/graphile-build-pg/src/index.ts index 77829b876b..626ad05661 100644 --- a/graphile-build/graphile-build-pg/src/index.ts +++ b/graphile-build/graphile-build-pg/src/index.ts @@ -80,6 +80,10 @@ declare global { behavior: string | string[]; deprecated: string | string[]; notNull: true; + /** For forward relations against polymorphic types, which type to choose? */ + returnType: string; + /** For backward relations against polymorphic types, which type to choose? */ + foreignReturnType: string; } interface PgCodecRefTags extends PgSmartTagsDict { diff --git a/graphile-build/graphile-build-pg/src/plugins/PgRelationsPlugin.ts b/graphile-build/graphile-build-pg/src/plugins/PgRelationsPlugin.ts index 5c9414abb5..f1092e3201 100644 --- a/graphile-build/graphile-build-pg/src/plugins/PgRelationsPlugin.ts +++ b/graphile-build/graphile-build-pg/src/plugins/PgRelationsPlugin.ts @@ -128,6 +128,10 @@ declare global { foreignSimpleFieldName?: string; /** The (generally plural) backward relation name, also used as a fallback from foreignSimpleFieldName, foreignSingleFieldName */ foreignFieldName?: string; + /** The GraphQL return type for the forward relation */ + returnType?: string; + /** The GraphQL return type for the backward relation */ + foreignReturnType?: string; } } @@ -933,9 +937,11 @@ function addRelations( } const isUnique = relation.isUnique ?? false; - const preferredTypeName = !relation.isReferencee - ? tagToString(relation.extensions?.tags?.returnType) - : null; + const preferredTypeName = tagToString( + relation.isReferencee + ? relation.extensions?.tags?.foreignReturnType + : relation.extensions?.tags?.returnType, + ); const otherCodec = remoteResource.codec; const typeName = preferredTypeName ?? build.inflection.tableType(otherCodec); diff --git a/postgraphile/postgraphile/__tests__/kitchen-sink-data.sql b/postgraphile/postgraphile/__tests__/kitchen-sink-data.sql index 6516fd14c4..871e27a75e 100644 --- a/postgraphile/postgraphile/__tests__/kitchen-sink-data.sql +++ b/postgraphile/postgraphile/__tests__/kitchen-sink-data.sql @@ -632,7 +632,7 @@ update polymorphic.single_table_items insert into polymorphic.foreign_key_return_type_tests (id, topic_id) values - (1, 1); + (4, 1); alter sequence polymorphic.foreign_key_return_type_tests_id_seq restart with 9999; insert into polymorphic.single_table_item_relations diff --git a/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql b/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql index cadab7ffaa..266400a94c 100644 --- a/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql +++ b/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql @@ -1468,9 +1468,10 @@ create table polymorphic.foreign_key_return_type_tests ( ); comment on table polymorphic.foreign_key_return_type_tests is E'@behavior -insert -update -delete -filter -filterBy -order -orderBy'; comment on constraint foreign_key_return_type_tests_topic_fkey on polymorphic.foreign_key_return_type_tests is $$ - @behavior -manyRelation:resource:list -manyRelation:resource:connection @fieldName topicByReturnType @returnType SingleTableTopic + @foreignFieldName childTopicsByReturnType + @foreignReturnType SingleTablePost $$; create table polymorphic.single_table_item_relations ( diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.json5 b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.json5 index 982789d683..76848a2e6d 100644 --- a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.json5 +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.json5 @@ -186,6 +186,24 @@ }, }, }, + { + name: "childTopicsByReturnType", + type: { + name: null, + ofType: { + name: "SingleTablePostConnection", + }, + }, + }, + { + name: "childTopicsByReturnTypeList", + type: { + name: null, + ofType: { + name: null, + }, + }, + }, { name: "singleTableItemRelationsByChildId", type: { diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.json5 b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.json5 index 579dbb9850..1ec0d18b60 100644 --- a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.json5 +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.json5 @@ -1,37 +1,16 @@ { - __type: { - fields: [ - { - name: "nodeId", - type: { - name: null, - }, - }, - { - name: "id", - type: { - name: null, - }, - }, - { - name: "topicId", - type: { - name: "Int", - }, - }, - { - name: "topicByReturnType", - type: { - name: "SingleTableTopic", - }, - }, - ], + postType: { + fields: "", + }, + topicType: { + fields: "", }, allForeignKeyReturnTypeTests: { nodes: [ { - id: 1, + id: 4, topicByReturnType: { + __typename: "SingleTableTopic", id: 1, title: "PostGraphile version 5", }, diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.test.graphql b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.test.graphql index 021c582fcf..eaa2d2dc67 100644 --- a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.test.graphql +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-foreign-key.test.graphql @@ -1,14 +1,40 @@ ## expect(errors).toBeFalsy() -## expect(JSON.stringify(data.__type.fields)).toContain("SingleTableTopic") #> schema: ["polymorphic"] #> simpleCollections: "both" +#> mask: ["postType.fields", "topicType.fields"] { - __type(name: "ForeignKeyReturnTypeTest") { + postType: __type(name: "ForeignKeyReturnTypeTest") { fields { name type { name + ofType { + name + ofType { + name + ofType { + name + } + } + } + } + } + } + topicType: __type(name: "SingleTableTopic") { + fields { + name + type { + name + ofType { + name + ofType { + name + ofType { + name + } + } + } } } } @@ -16,6 +42,7 @@ nodes { id topicByReturnType { + __typename id title } diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs index 15a634693a..a32180f1e1 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs @@ -3578,9 +3578,10 @@ const registryConfig = { isUnique: true, extensions: { tags: { - behavior: ["-manyRelation:resource:list -manyRelation:resource:connection"], fieldName: "topicByReturnType", - returnType: "SingleTableTopic" + returnType: "SingleTableTopic", + foreignFieldName: "childTopicsByReturnType", + foreignReturnType: "SingleTablePost" } } } @@ -4018,7 +4019,7 @@ const registryConfig = { } } }, - foreignKeyReturnTypeTestsByTheirTopicId: { + childTopicsByReturnType: { localCodec: singleTableItemsCodec, remoteResourceOptions: foreign_key_return_type_tests_resourceOptionsConfig, localAttributes: ["id"], @@ -4026,9 +4027,10 @@ const registryConfig = { isReferencee: true, extensions: { tags: { - behavior: ["-manyRelation:resource:list -manyRelation:resource:connection"], fieldName: "topicByReturnType", - returnType: "SingleTableTopic" + returnType: "SingleTableTopic", + foreignFieldName: "childTopicsByReturnType", + foreignReturnType: "SingleTablePost" } } }, @@ -4211,6 +4213,13 @@ function applyOrderByArgToConnection(parent, $connection, value) { const $select = $connection.getSubplan(); value.apply($select); } +const otherSource_foreign_key_return_type_testsPgResource = registry.pgResources["foreign_key_return_type_tests"]; +const SingleTableTopic_childTopicsByReturnTypePlan = $record => { + const $records = otherSource_foreign_key_return_type_testsPgResource.find({ + topic_id: $record.get("id") + }); + return connection($records); +}; const otherSource_single_table_item_relationsPgResource = registry.pgResources["single_table_item_relations"]; const SingleTableTopic_singleTableItemRelationsByChildIdPlan = $record => { const $records = otherSource_single_table_item_relationsPgResource.find({ @@ -4924,7 +4933,6 @@ const Collection_typeNameFromType = ((interfaceTypeName, polymorphism) => { typeNameFromType.displayName = `${interfaceTypeName}_typeNameFromType`; return typeNameFromType; })("Collection", spec_collections.polymorphism); -const resource_foreign_key_return_type_testsPgResource = registry.pgResources["foreign_key_return_type_tests"]; const argDetailsSimple_relational_topic_by_id_fn = [{ graphqlArgName: "id", pgCodec: TYPES.int, @@ -5679,6 +5687,27 @@ export const typeDefs = /* GraphQL */`type SingleTableTopic implements SingleTab orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -5850,6 +5879,27 @@ interface SingleTableItem { after: Cursor ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -6812,6 +6862,34 @@ enum ApplicationsOrderBy { LAST_DEPLOYED_DESC } +"""A connection to a list of \`SingleTablePost\` values.""" +type SingleTablePostConnection { + """A list of \`SingleTablePost\` objects.""" + nodes: [SingleTablePost]! + + """ + A list of edges which contains the \`SingleTablePost\` and cursor to aid in pagination. + """ + edges: [SingleTablePostEdge]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* \`SingleTableItem\` you could get from the connection. + """ + totalCount: Int! +} + +"""A \`SingleTablePost\` edge in the connection.""" +type SingleTablePostEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The \`SingleTablePost\` at the end of the edge.""" + node: SingleTablePost +} + """A connection to a list of \`SingleTableItemRelation\` values.""" type SingleTableItemRelationsConnection { """A list of \`SingleTableItemRelation\` objects.""" @@ -7056,6 +7134,27 @@ type SingleTablePost implements SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -7293,6 +7392,27 @@ type SingleTableDivider implements SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -7495,6 +7615,27 @@ type SingleTableChecklist implements SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -7707,6 +7848,27 @@ type SingleTableChecklistItem implements SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -11384,7 +11546,7 @@ export const objects = { }, allForeignKeyReturnTypeTests: { plan() { - return connection(resource_foreign_key_return_type_testsPgResource.find()); + return connection(otherSource_foreign_key_return_type_testsPgResource.find()); }, args: { first: applyFirstArg, @@ -11672,7 +11834,7 @@ export const objects = { foreignKeyReturnTypeTestById(_$root, { $id }) { - return resource_foreign_key_return_type_testsPgResource.get({ + return otherSource_foreign_key_return_type_testsPgResource.get({ id: $id }); }, @@ -11996,7 +12158,7 @@ export const objects = { for (const pkCol of foreign_key_return_type_testsUniques[0].attributes) { spec[pkCol] = get2($specifier, pkCol); } - return resource_foreign_key_return_type_testsPgResource.get(spec); + return otherSource_foreign_key_return_type_testsPgResource.get(spec); } }, ForeignKeyReturnTypeTestsConnection: { @@ -13547,6 +13709,16 @@ export const objects = { plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, @@ -13634,6 +13806,16 @@ export const objects = { plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, @@ -13722,6 +13904,16 @@ export const objects = { plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, @@ -13858,6 +14050,16 @@ export const objects = { plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, @@ -13944,11 +14146,27 @@ export const objects = { updatedAt: SingleTableTopic_updatedAtPlan } }, + SingleTablePostConnection: { + assertStep: ConnectionStep, + plans: { + totalCount: totalCountConnectionPlan + } + }, SingleTableTopic: { assertStep: assertPgClassSingleStep, plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql index ac3eb0ca64..1d9d218e79 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql @@ -4123,6 +4123,27 @@ type SeriesCollection implements Collection { type SingleTableChecklist implements SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! id: Int! isExplicitlyArchived: Boolean! @@ -4330,6 +4351,27 @@ type SingleTableChecklist implements SingleTableItem { type SingleTableChecklistItem implements SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! description: String id: Int! @@ -4537,6 +4579,27 @@ type SingleTableChecklistItem implements SingleTableItem { type SingleTableDivider implements SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! color: String createdAt: Datetime! id: Int! @@ -4740,6 +4803,27 @@ type SingleTableDivider implements SingleTableItem { interface SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! id: Int! isExplicitlyArchived: Boolean! @@ -5108,6 +5192,27 @@ enum SingleTableItemsOrderBy { type SingleTablePost implements SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! description: String id: Int! @@ -5313,9 +5418,58 @@ type SingleTablePost implements SingleTableItem { updatedAt: Datetime! } +"""A connection to a list of `SingleTablePost` values.""" +type SingleTablePostConnection { + """ + A list of edges which contains the `SingleTablePost` and cursor to aid in pagination. + """ + edges: [SingleTablePostEdge]! + + """A list of `SingleTablePost` objects.""" + nodes: [SingleTablePost]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* `SingleTableItem` you could get from the connection. + """ + totalCount: Int! +} + +"""A `SingleTablePost` edge in the connection.""" +type SingleTablePostEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The `SingleTablePost` at the end of the edge.""" + node: SingleTablePost +} + type SingleTableTopic implements SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! id: Int! isExplicitlyArchived: Boolean! diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs index 4316b4ad0c..5e3b749e97 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs @@ -3591,9 +3591,10 @@ const registryConfig = { isUnique: true, extensions: { tags: { - behavior: ["-manyRelation:resource:list -manyRelation:resource:connection"], fieldName: "topicByReturnType", - returnType: "SingleTableTopic" + returnType: "SingleTableTopic", + foreignFieldName: "childTopicsByReturnType", + foreignReturnType: "SingleTablePost" } } } @@ -4031,7 +4032,7 @@ const registryConfig = { } } }, - foreignKeyReturnTypeTestsByTheirTopicId: { + childTopicsByReturnType: { localCodec: singleTableItemsCodec, remoteResourceOptions: foreign_key_return_type_tests_resourceOptionsConfig, localAttributes: ["id"], @@ -4039,9 +4040,10 @@ const registryConfig = { isReferencee: true, extensions: { tags: { - behavior: ["-manyRelation:resource:list -manyRelation:resource:connection"], fieldName: "topicByReturnType", - returnType: "SingleTableTopic" + returnType: "SingleTableTopic", + foreignFieldName: "childTopicsByReturnType", + foreignReturnType: "SingleTablePost" } } }, @@ -4263,6 +4265,13 @@ function applyOrderByArgToConnection(parent, $connection, value) { const $select = $connection.getSubplan(); value.apply($select); } +const otherSource_foreign_key_return_type_testsPgResource = registry.pgResources["foreign_key_return_type_tests"]; +const SingleTableTopic_childTopicsByReturnTypePlan = $record => { + const $records = otherSource_foreign_key_return_type_testsPgResource.find({ + topic_id: $record.get("id") + }); + return connection($records); +}; const otherSource_single_table_item_relationsPgResource = registry.pgResources["single_table_item_relations"]; const SingleTableTopic_singleTableItemRelationsByChildIdPlan = $record => { const $records = otherSource_single_table_item_relationsPgResource.find({ @@ -4331,12 +4340,11 @@ const makeTableNodeIdHandler = ({ deprecationReason }; }; -const spec_resource_foreign_key_return_type_testsPgResource = registry.pgResources["foreign_key_return_type_tests"]; const nodeIdHandler_ForeignKeyReturnTypeTest = makeTableNodeIdHandler({ typeName: "ForeignKeyReturnTypeTest", identifier: "foreign_key_return_type_tests", nodeIdCodec: base64JSONNodeIdCodec, - resource: spec_resource_foreign_key_return_type_testsPgResource, + resource: otherSource_foreign_key_return_type_testsPgResource, pk: foreign_key_return_type_testsUniques[0].attributes }); const spec_resource_organizationsPgResource = registry.pgResources["organizations"]; @@ -6418,6 +6426,27 @@ export const typeDefs = /* GraphQL */`type SingleTableTopic implements SingleTab orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -6593,6 +6622,27 @@ interface SingleTableItem implements Node { after: Cursor ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -7991,6 +8041,34 @@ enum ApplicationsOrderBy { LAST_DEPLOYED_DESC } +"""A connection to a list of \`SingleTablePost\` values.""" +type SingleTablePostConnection { + """A list of \`SingleTablePost\` objects.""" + nodes: [SingleTablePost]! + + """ + A list of edges which contains the \`SingleTablePost\` and cursor to aid in pagination. + """ + edges: [SingleTablePostEdge]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* \`SingleTableItem\` you could get from the connection. + """ + totalCount: Int! +} + +"""A \`SingleTablePost\` edge in the connection.""" +type SingleTablePostEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The \`SingleTablePost\` at the end of the edge.""" + node: SingleTablePost +} + """A connection to a list of \`SingleTableItemRelation\` values.""" type SingleTableItemRelationsConnection { """A list of \`SingleTableItemRelation\` objects.""" @@ -8247,6 +8325,27 @@ type SingleTablePost implements SingleTableItem & Node { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -8492,6 +8591,27 @@ type SingleTableDivider implements SingleTableItem & Node { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -8698,6 +8818,27 @@ type SingleTableChecklist implements SingleTableItem & Node { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -8914,6 +9055,27 @@ type SingleTableChecklistItem implements SingleTableItem & Node { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -15673,7 +15835,7 @@ export const objects = { }, allForeignKeyReturnTypeTests: { plan() { - return connection(spec_resource_foreign_key_return_type_testsPgResource.find()); + return connection(otherSource_foreign_key_return_type_testsPgResource.find()); }, args: { first: applyFirstArg, @@ -16015,7 +16177,7 @@ export const objects = { foreignKeyReturnTypeTestById(_$root, { $id }) { - return spec_resource_foreign_key_return_type_testsPgResource.get({ + return otherSource_foreign_key_return_type_testsPgResource.get({ id: $id }); }, @@ -17610,7 +17772,7 @@ export const objects = { for (const pkCol of foreign_key_return_type_testsUniques[0].attributes) { spec[pkCol] = get2($specifier, pkCol); } - return spec_resource_foreign_key_return_type_testsPgResource.get(spec); + return otherSource_foreign_key_return_type_testsPgResource.get(spec); } }, ForeignKeyReturnTypeTestsConnection: { @@ -19291,6 +19453,16 @@ export const objects = { plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, @@ -19382,6 +19554,16 @@ export const objects = { plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, @@ -19474,6 +19656,16 @@ export const objects = { plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, @@ -19622,6 +19814,16 @@ export const objects = { plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, @@ -19712,11 +19914,27 @@ export const objects = { updatedAt: SingleTableTopic_updatedAtPlan } }, + SingleTablePostConnection: { + assertStep: ConnectionStep, + plans: { + totalCount: totalCountConnectionPlan + } + }, SingleTableTopic: { assertStep: assertPgClassSingleStep, plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql index 73e94d9b7f..03cdb157cb 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql @@ -6749,6 +6749,27 @@ type SeriesCollection implements Collection & Node { type SingleTableChecklist implements Node & SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! id: Int! isExplicitlyArchived: Boolean! @@ -6961,6 +6982,27 @@ type SingleTableChecklist implements Node & SingleTableItem { type SingleTableChecklistItem implements Node & SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! description: String id: Int! @@ -7173,6 +7215,27 @@ type SingleTableChecklistItem implements Node & SingleTableItem { type SingleTableDivider implements Node & SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! color: String createdAt: Datetime! id: Int! @@ -7381,6 +7444,27 @@ type SingleTableDivider implements Node & SingleTableItem { interface SingleTableItem implements Node { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! id: Int! isExplicitlyArchived: Boolean! @@ -7794,6 +7878,27 @@ enum SingleTableItemsOrderBy { type SingleTablePost implements Node & SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! description: String id: Int! @@ -8004,9 +8109,58 @@ type SingleTablePost implements Node & SingleTableItem { updatedAt: Datetime! } +"""A connection to a list of `SingleTablePost` values.""" +type SingleTablePostConnection { + """ + A list of edges which contains the `SingleTablePost` and cursor to aid in pagination. + """ + edges: [SingleTablePostEdge]! + + """A list of `SingleTablePost` objects.""" + nodes: [SingleTablePost]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* `SingleTableItem` you could get from the connection. + """ + totalCount: Int! +} + +"""A `SingleTablePost` edge in the connection.""" +type SingleTablePostEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The `SingleTablePost` at the end of the edge.""" + node: SingleTablePost +} + type SingleTableTopic implements Node & SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! id: Int! isExplicitlyArchived: Boolean! diff --git a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs index ab485c3b3d..294d8935cc 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs @@ -3578,9 +3578,10 @@ const registryConfig = { isUnique: true, extensions: { tags: { - behavior: ["-manyRelation:resource:list -manyRelation:resource:connection"], fieldName: "topicByReturnType", - returnType: "SingleTableTopic" + returnType: "SingleTableTopic", + foreignFieldName: "childTopicsByReturnType", + foreignReturnType: "SingleTablePost" } } } @@ -4018,7 +4019,7 @@ const registryConfig = { } } }, - foreignKeyReturnTypeTestsByTheirTopicId: { + childTopicsByReturnType: { localCodec: singleTableItemsCodec, remoteResourceOptions: foreign_key_return_type_tests_resourceOptionsConfig, localAttributes: ["id"], @@ -4026,9 +4027,10 @@ const registryConfig = { isReferencee: true, extensions: { tags: { - behavior: ["-manyRelation:resource:list -manyRelation:resource:connection"], fieldName: "topicByReturnType", - returnType: "SingleTableTopic" + returnType: "SingleTableTopic", + foreignFieldName: "childTopicsByReturnType", + foreignReturnType: "SingleTablePost" } } }, @@ -4211,6 +4213,13 @@ function applyOrderByArgToConnection(parent, $connection, value) { const $select = $connection.getSubplan(); value.apply($select); } +const otherSource_foreign_key_return_type_testsPgResource = registry.pgResources["foreign_key_return_type_tests"]; +const SingleTableTopic_childTopicsByReturnTypePlan = $record => { + const $records = otherSource_foreign_key_return_type_testsPgResource.find({ + topic_id: $record.get("id") + }); + return connection($records); +}; const otherSource_single_table_item_relationsPgResource = registry.pgResources["single_table_item_relations"]; const SingleTableTopic_singleTableItemRelationsByChildIdPlan = $record => { const $records = otherSource_single_table_item_relationsPgResource.find({ @@ -5163,7 +5172,6 @@ const Collection_typeNameFromType = ((interfaceTypeName, polymorphism) => { typeNameFromType.displayName = `${interfaceTypeName}_typeNameFromType`; return typeNameFromType; })("Collection", spec_collections.polymorphism); -const resource_foreign_key_return_type_testsPgResource = registry.pgResources["foreign_key_return_type_tests"]; const argDetailsSimple_relational_topic_by_id_fn = [{ graphqlArgName: "id", pgCodec: TYPES.int, @@ -5848,6 +5856,27 @@ export const typeDefs = /* GraphQL */`type SingleTableTopic implements SingleTab orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -6019,6 +6048,27 @@ interface SingleTableItem { after: Cursor ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -7369,6 +7419,34 @@ enum ApplicationsOrderBy { LAST_DEPLOYED_DESC } +"""A connection to a list of \`SingleTablePost\` values.""" +type SingleTablePostConnection { + """A list of \`SingleTablePost\` objects.""" + nodes: [SingleTablePost]! + + """ + A list of edges which contains the \`SingleTablePost\` and cursor to aid in pagination. + """ + edges: [SingleTablePostEdge]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* \`SingleTableItem\` you could get from the connection. + """ + totalCount: Int! +} + +"""A \`SingleTablePost\` edge in the connection.""" +type SingleTablePostEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The \`SingleTablePost\` at the end of the edge.""" + node: SingleTablePost +} + """A connection to a list of \`SingleTableItemRelation\` values.""" type SingleTableItemRelationsConnection { """A list of \`SingleTableItemRelation\` objects.""" @@ -7613,6 +7691,27 @@ type SingleTablePost implements SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -7850,6 +7949,27 @@ type SingleTableDivider implements SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -8052,6 +8172,27 @@ type SingleTableChecklist implements SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -8264,6 +8405,27 @@ type SingleTableChecklistItem implements SingleTableItem { orderBy: [SingleTableItemsOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemsConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -14140,7 +14302,7 @@ export const objects = { }, allForeignKeyReturnTypeTests: { plan() { - return connection(resource_foreign_key_return_type_testsPgResource.find()); + return connection(otherSource_foreign_key_return_type_testsPgResource.find()); }, args: { first: applyFirstArg, @@ -14470,7 +14632,7 @@ export const objects = { foreignKeyReturnTypeTestById(_$root, { $id }) { - return resource_foreign_key_return_type_testsPgResource.get({ + return otherSource_foreign_key_return_type_testsPgResource.get({ id: $id }); }, @@ -15611,7 +15773,7 @@ export const objects = { for (const pkCol of foreign_key_return_type_testsUniques[0].attributes) { spec[pkCol] = get2($specifier, pkCol); } - return resource_foreign_key_return_type_testsPgResource.get(spec); + return otherSource_foreign_key_return_type_testsPgResource.get(spec); } }, ForeignKeyReturnTypeTestsConnection: { @@ -17236,6 +17398,16 @@ export const objects = { plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, @@ -17323,6 +17495,16 @@ export const objects = { plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, @@ -17411,6 +17593,16 @@ export const objects = { plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, @@ -17547,6 +17739,16 @@ export const objects = { plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, @@ -17633,11 +17835,27 @@ export const objects = { updatedAt: SingleTableTopic_updatedAtPlan } }, + SingleTablePostConnection: { + assertStep: ConnectionStep, + plans: { + totalCount: totalCountConnectionPlan + } + }, SingleTableTopic: { assertStep: assertPgClassSingleStep, plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, diff --git a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql index 7697d169f8..ec0863a1cd 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql @@ -6015,6 +6015,27 @@ type SeriesCollection implements Collection { type SingleTableChecklist implements SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! id: Int! isExplicitlyArchived: Boolean! @@ -6222,6 +6243,27 @@ type SingleTableChecklist implements SingleTableItem { type SingleTableChecklistItem implements SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! description: String id: Int! @@ -6429,6 +6471,27 @@ type SingleTableChecklistItem implements SingleTableItem { type SingleTableDivider implements SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! color: String createdAt: Datetime! id: Int! @@ -6632,6 +6695,27 @@ type SingleTableDivider implements SingleTableItem { interface SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! id: Int! isExplicitlyArchived: Boolean! @@ -7030,6 +7114,27 @@ enum SingleTableItemsOrderBy { type SingleTablePost implements SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! description: String id: Int! @@ -7235,9 +7340,58 @@ type SingleTablePost implements SingleTableItem { updatedAt: Datetime! } +"""A connection to a list of `SingleTablePost` values.""" +type SingleTablePostConnection { + """ + A list of edges which contains the `SingleTablePost` and cursor to aid in pagination. + """ + edges: [SingleTablePostEdge]! + + """A list of `SingleTablePost` objects.""" + nodes: [SingleTablePost]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* `SingleTableItem` you could get from the connection. + """ + totalCount: Int! +} + +"""A `SingleTablePost` edge in the connection.""" +type SingleTablePostEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The `SingleTablePost` at the end of the edge.""" + node: SingleTablePost +} + type SingleTableTopic implements SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! id: Int! isExplicitlyArchived: Boolean! diff --git a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs index 8a9e29ce60..afe362bef9 100644 --- a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs @@ -3572,9 +3572,10 @@ const registryConfig = { isUnique: true, extensions: { tags: { - behavior: ["-manyRelation:resource:list -manyRelation:resource:connection"], fieldName: "topicByReturnType", - returnType: "SingleTableTopic" + returnType: "SingleTableTopic", + foreignFieldName: "childTopicsByReturnType", + foreignReturnType: "SingleTablePost" } } } @@ -4012,7 +4013,7 @@ const registryConfig = { } } }, - foreignKeyReturnTypeTestsByTheirTopicId: { + childTopicsByReturnType: { localCodec: singleTableItemsCodec, remoteResourceOptions: foreign_key_return_type_tests_resourceOptionsConfig, localAttributes: ["id"], @@ -4020,9 +4021,10 @@ const registryConfig = { isReferencee: true, extensions: { tags: { - behavior: ["-manyRelation:resource:list -manyRelation:resource:connection"], fieldName: "topicByReturnType", - returnType: "SingleTableTopic" + returnType: "SingleTableTopic", + foreignFieldName: "childTopicsByReturnType", + foreignReturnType: "SingleTablePost" } } }, @@ -4208,6 +4210,13 @@ function applyOrderByArgToConnection(parent, $connection, value) { const $select = $connection.getSubplan(); value.apply($select); } +const otherSource_foreign_key_return_type_testsPgResource = registry.pgResources["foreign_key_return_type_tests"]; +const SingleTableTopic_childTopicsByReturnTypePlan = $record => { + const $records = otherSource_foreign_key_return_type_testsPgResource.find({ + topic_id: $record.get("id") + }); + return connection($records); +}; const otherSource_single_table_item_relationsPgResource = registry.pgResources["single_table_item_relations"]; const SingleTableTopic_singleTableItemRelationsByChildIdPlan = $record => { const $records = otherSource_single_table_item_relationsPgResource.find({ @@ -5604,7 +5613,6 @@ const Collection_typeNameFromType = ((interfaceTypeName, polymorphism) => { return typeNameFromType; })("Collection", spec_collections.polymorphism); const JSONSerialize = value => value; -const resource_foreign_key_return_type_testsPgResource = registry.pgResources["foreign_key_return_type_tests"]; const argDetailsSimple_relational_topic_by_id_fn = [{ graphqlArgName: "id", pgCodec: TYPES.int, @@ -5910,6 +5918,27 @@ export const typeDefs = /* GraphQL */`type SingleTableTopic implements SingleTab orderBy: [SingleTableItemOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -6081,6 +6110,27 @@ interface SingleTableItem { after: Cursor ): SingleTableItemConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -8057,6 +8107,34 @@ enum RelationalItemOrderBy { ARCHIVED_AT_DESC } +"""A connection to a list of \`SingleTablePost\` values.""" +type SingleTablePostConnection { + """A list of \`SingleTablePost\` objects.""" + nodes: [SingleTablePost]! + + """ + A list of edges which contains the \`SingleTablePost\` and cursor to aid in pagination. + """ + edges: [SingleTablePostEdge]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* \`SingleTableItem\` you could get from the connection. + """ + totalCount: Int! +} + +"""A \`SingleTablePost\` edge in the connection.""" +type SingleTablePostEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The \`SingleTablePost\` at the end of the edge.""" + node: SingleTablePost +} + """A connection to a list of \`SingleTableItemRelation\` values.""" type SingleTableItemRelationConnection { """A list of \`SingleTableItemRelation\` objects.""" @@ -8295,6 +8373,27 @@ type SingleTablePost implements SingleTableItem { orderBy: [SingleTableItemOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -8526,6 +8625,27 @@ type SingleTableDivider implements SingleTableItem { orderBy: [SingleTableItemOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -8722,6 +8842,27 @@ type SingleTableChecklist implements SingleTableItem { orderBy: [SingleTableItemOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -8928,6 +9069,27 @@ type SingleTableChecklistItem implements SingleTableItem { orderBy: [SingleTableItemOrderBy!] = [PRIMARY_KEY_ASC] ): SingleTableItemConnection! + """Reads and enables pagination through a set of \`SingleTablePost\`.""" + childTopicsByReturnType( + """Only read the first \`n\` values of the set.""" + first: Int + + """Only read the last \`n\` values of the set.""" + last: Int + + """ + Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor + based pagination. May not be used with \`last\`. + """ + offset: Int + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Read all values in the set after (below) this cursor.""" + after: Cursor + ): SingleTablePostConnection! + """ Reads and enables pagination through a set of \`SingleTableItemRelation\`. """ @@ -15588,7 +15750,7 @@ export const objects = { }, allForeignKeyReturnTypeTests: { plan() { - return connection(resource_foreign_key_return_type_testsPgResource.find()); + return connection(otherSource_foreign_key_return_type_testsPgResource.find()); }, args: { first: applyFirstArg, @@ -15962,7 +16124,7 @@ export const objects = { foreignKeyReturnTypeTestByRowId(_$root, { $rowId }) { - return resource_foreign_key_return_type_testsPgResource.get({ + return otherSource_foreign_key_return_type_testsPgResource.get({ id: $rowId }); }, @@ -17506,7 +17668,7 @@ export const objects = { for (const pkCol of foreign_key_return_type_testsUniques[0].attributes) { spec[pkCol] = get2($specifier, pkCol); } - return resource_foreign_key_return_type_testsPgResource.get(spec); + return otherSource_foreign_key_return_type_testsPgResource.get(spec); } }, ForeignKeyReturnTypeTestConnection: { @@ -19220,6 +19382,16 @@ export const objects = { plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, @@ -19306,6 +19478,16 @@ export const objects = { plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, @@ -19393,6 +19575,16 @@ export const objects = { plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, @@ -19529,6 +19721,16 @@ export const objects = { plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, @@ -19614,11 +19816,27 @@ export const objects = { updatedAt: SingleTableTopic_updatedAtPlan } }, + SingleTablePostConnection: { + assertStep: ConnectionStep, + plans: { + totalCount: totalCountConnectionPlan + } + }, SingleTableTopic: { assertStep: assertPgClassSingleStep, plans: { archivedAt: SingleTableTopic_archivedAtPlan, authorId: SingleTableTopic_authorIdPlan, + childTopicsByReturnType: { + plan: SingleTableTopic_childTopicsByReturnTypePlan, + args: { + first: applyFirstArg, + last: applyLastArg, + offset: applyOffsetArg, + before: applyBeforeArg, + after: applyAfterArg + } + }, createdAt: SingleTableTopic_createdAtPlan, isExplicitlyArchived: SingleTableTopic_isExplicitlyArchivedPlan, meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, diff --git a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql index a4f4ecf74f..efa51cfa08 100644 --- a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql @@ -7157,6 +7157,27 @@ type SeriesCollection implements Collection { type SingleTableChecklist implements SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! isExplicitlyArchived: Boolean! meaningOfLife: Int @@ -7358,6 +7379,27 @@ type SingleTableChecklist implements SingleTableItem { type SingleTableChecklistItem implements SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! description: String isExplicitlyArchived: Boolean! @@ -7559,6 +7601,27 @@ type SingleTableChecklistItem implements SingleTableItem { type SingleTableDivider implements SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! color: String createdAt: Datetime! isExplicitlyArchived: Boolean! @@ -7756,6 +7819,27 @@ type SingleTableDivider implements SingleTableItem { interface SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! isExplicitlyArchived: Boolean! parentId: Int @@ -8152,6 +8236,27 @@ input SingleTableItemRelationPatch { type SingleTablePost implements SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! description: String isExplicitlyArchived: Boolean! @@ -8351,9 +8456,58 @@ type SingleTablePost implements SingleTableItem { updatedAt: Datetime! } +"""A connection to a list of `SingleTablePost` values.""" +type SingleTablePostConnection { + """ + A list of edges which contains the `SingleTablePost` and cursor to aid in pagination. + """ + edges: [SingleTablePostEdge]! + + """A list of `SingleTablePost` objects.""" + nodes: [SingleTablePost]! + + """Information to aid in pagination.""" + pageInfo: PageInfo! + + """ + The count of *all* `SingleTableItem` you could get from the connection. + """ + totalCount: Int! +} + +"""A `SingleTablePost` edge in the connection.""" +type SingleTablePostEdge { + """A cursor for use in pagination.""" + cursor: Cursor + + """The `SingleTablePost` at the end of the edge.""" + node: SingleTablePost +} + type SingleTableTopic implements SingleTableItem { archivedAt: Datetime authorId: Int! + + """Reads and enables pagination through a set of `SingleTablePost`.""" + childTopicsByReturnType( + """Read all values in the set after (below) this cursor.""" + after: Cursor + + """Read all values in the set before (above) this cursor.""" + before: Cursor + + """Only read the first `n` values of the set.""" + first: Int + + """Only read the last `n` values of the set.""" + last: Int + + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + ): SingleTablePostConnection! createdAt: Datetime! isExplicitlyArchived: Boolean! meaningOfLife: Int diff --git a/postgraphile/website/postgraphile/smart-tags.md b/postgraphile/website/postgraphile/smart-tags.md index d8f9e35d04..c89e00071c 100644 --- a/postgraphile/website/postgraphile/smart-tags.md +++ b/postgraphile/website/postgraphile/smart-tags.md @@ -265,18 +265,95 @@ Applies to: - Custom Query functions - Custom Mutation functions - Computed Column functions +- foreign key constraints: the related type for forward relationship fields Details the _named_ GraphQL type to use to represent the result of the function -(this may then be wrapped in a list or connection or non-null or similar, if -the function demands it). This type must be compatible with the derived type; -currently this means that if the function returns a polymorphic type then -the named type must either be the polymorphic type itself, or one of its -implementations. +or foreign-key relationship field. This may then be wrapped in a list or +connection or non-null or similar, if needed. + +This type must be compatible with the derived type; currently this means that +if the function returns a polymorphic type, or the constraint references a +polymorphic table type, then the named type must either be the polymorphic type +itself, or one of its implementations. + +For foreign key constraints, `@returnType` is useful when the related table is +polymorphic but this relationship only targets one concrete (monomorphic) +GraphQL type. This applies to the forward relationship field; for the backward +relationship fields, use `@foreignReturnType`. + +```json5 title="postgraphile.tags.json5" +{ + version: 1, + config: { + class: { + single_table_items: { + constraint: { + single_table_items_root_topic_fkey: { + tags: { + fieldName: "rootTopic", + returnType: "SingleTableTopic", + }, + }, + }, + }, + }, + }, +} +``` + +```sql +comment on constraint single_table_items_root_topic_fkey + on polymorphic.single_table_items is + E'@fieldName rootTopic\n@returnType SingleTableTopic'; +``` + +## @foreignReturnType + +Applies to: + +- foreign key constraints: the related type for backward relationship fields + +Details the _named_ GraphQL type to use to represent the result of the backward +foreign-key relationship field. This may then be wrapped in a list or connection +or non-null or similar, if needed. + +This is useful when the referencing table is polymorphic but the backward +relationship only targets one concrete (monomorphic) GraphQL type. + +```json5 title="postgraphile.tags.json5" +{ + version: 1, + config: { + class: { + single_table_items: { + constraint: { + single_table_items_root_topic_fkey: { + tags: { + foreignFieldName: "postsWithThisRootTopic", + foreignReturnType: "SingleTablePost", + }, + }, + }, + }, + }, + }, +} +``` + +```sql +comment on constraint single_table_items_root_topic_fkey + on polymorphic.single_table_items is + $$ + @foreignFieldName postsWithThisRootTopic + @foreignReturnType SingleTablePost + $$; +``` :::warning -We trust that you will ensure that results from the function conform to the -type specified; if you break this then Weird Things may occur. +We trust that you will ensure that results from the function or foreign-key +relationship conform to the type specified; if you break this then Weird Things +may occur. ::: From 43f8e061a7867a44d13644e8dd1257e781a3d348 Mon Sep 17 00:00:00 2001 From: tsnobip Date: Fri, 5 Jun 2026 15:18:02 +0200 Subject: [PATCH 4/6] Add applyToType for computed columns --- graphile-build/graphile-build-pg/src/index.ts | 2 + .../src/plugins/PgCustomTypeFieldPlugin.ts | 10 + .../__tests__/kitchen-sink-schema.sql | 10 + .../apply-to-type-computed-column.json5 | 393 ++++++++++++++++++ .../apply-to-type-computed-column.mermaid | 59 +++ .../apply-to-type-computed-column.sql | 9 + ...apply-to-type-computed-column.test.graphql | 39 ++ .../return-type-computed-column-setof.json5 | 7 + .../polymorphic-auto-add-types.1.export.mjs | 31 ++ .../v4/polymorphic-auto-add-types.1.graphql | 1 + .../schema/v4/polymorphic.1.export.mjs | 31 ++ .../__tests__/schema/v4/polymorphic.1.graphql | 1 + .../skipNodePlugin.polymorphic.1.export.mjs | 31 ++ .../v4/skipNodePlugin.polymorphic.1.graphql | 1 + .../skipNodePlugin.polymorphic.1.export.mjs | 31 ++ .../v5/skipNodePlugin.polymorphic.1.graphql | 1 + .../website/postgraphile/smart-tags.md | 40 ++ 17 files changed, 697 insertions(+) create mode 100644 postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.json5 create mode 100644 postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.mermaid create mode 100644 postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.sql create mode 100644 postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.test.graphql diff --git a/graphile-build/graphile-build-pg/src/index.ts b/graphile-build/graphile-build-pg/src/index.ts index 626ad05661..b29ea501f0 100644 --- a/graphile-build/graphile-build-pg/src/index.ts +++ b/graphile-build/graphile-build-pg/src/index.ts @@ -62,6 +62,8 @@ declare global { nodeIdCodec: string; /** For functions returning polymorphic type, which type to choose? */ returnType: string; + /** For computed attribute functions, which GraphQL type should receive this field? */ + applyToType: string; /** For enum tables; we shouldn't expose these through GraphQL */ enum: string | true; diff --git a/graphile-build/graphile-build-pg/src/plugins/PgCustomTypeFieldPlugin.ts b/graphile-build/graphile-build-pg/src/plugins/PgCustomTypeFieldPlugin.ts index ca1ebf8b67..9851591c81 100644 --- a/graphile-build/graphile-build-pg/src/plugins/PgCustomTypeFieldPlugin.ts +++ b/graphile-build/graphile-build-pg/src/plugins/PgCustomTypeFieldPlugin.ts @@ -1158,6 +1158,16 @@ function modFields( return procSources.reduce( (memo, resource) => build.recoverable(memo, () => { + const applyToType = tagToString(resource.extensions?.tags?.applyToType); + const shouldSkipForApplyToType = + isRootQuery || isRootMutation + ? false + : applyToType + ? applyToType !== SelfName + : false; + if (shouldSkipForApplyToType) { + return memo; + } // "Computed attributes" skip a parameter const offset = isRootMutation || isRootQuery ? 0 : 1; diff --git a/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql b/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql index 266400a94c..3a58b4e517 100644 --- a/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql +++ b/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql @@ -1440,6 +1440,16 @@ create function polymorphic.single_table_items_meaning_of_life(sti polymorphic.s select 42; $$ language sql stable; +create function polymorphic.single_table_items_post_only( + sti polymorphic.single_table_items +) +returns text as $$ +select 'post only: ' || sti.title; +$$ language sql stable; +comment on function polymorphic.single_table_items_post_only( + polymorphic.single_table_items +) is '@applyToType SingleTablePost'; + create function polymorphic.all_single_tables () returns setof polymorphic.single_table_items as $$ select * from polymorphic.single_table_items diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.json5 b/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.json5 new file mode 100644 index 0000000000..12f7fa96e2 --- /dev/null +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.json5 @@ -0,0 +1,393 @@ +{ + interfaceType: { + fields: [ + { + name: "nodeId", + }, + { + name: "id", + }, + { + name: "type", + }, + { + name: "parentId", + }, + { + name: "rootTopicId", + }, + { + name: "authorId", + }, + { + name: "position", + }, + { + name: "createdAt", + }, + { + name: "updatedAt", + }, + { + name: "isExplicitlyArchived", + }, + { + name: "archivedAt", + }, + { + name: "personByAuthorId", + }, + { + name: "singleTableItemByParentId", + }, + { + name: "singleTableItemsByParentId", + }, + { + name: "singleTableItemsByParentIdList", + }, + { + name: "childTopicsByReturnType", + }, + { + name: "childTopicsByReturnTypeList", + }, + { + name: "singleTableItemRelationsByChildId", + }, + { + name: "singleTableItemRelationsByChildIdList", + }, + { + name: "singleTableItemRelationsByParentId", + }, + { + name: "singleTableItemRelationsByParentIdList", + }, + { + name: "singleTableItemRelationCompositePksByChildId", + }, + { + name: "singleTableItemRelationCompositePksByChildIdList", + }, + { + name: "singleTableItemRelationCompositePksByParentId", + }, + { + name: "singleTableItemRelationCompositePksByParentIdList", + }, + { + name: "rootTopic", + }, + ], + }, + postType: { + fields: [ + { + name: "nodeId", + }, + { + name: "postOnly", + }, + { + name: "meaningOfLife", + }, + { + name: "topics", + }, + { + name: "topicsList", + }, + { + name: "id", + }, + { + name: "type", + }, + { + name: "parentId", + }, + { + name: "rootTopicId", + }, + { + name: "authorId", + }, + { + name: "position", + }, + { + name: "createdAt", + }, + { + name: "updatedAt", + }, + { + name: "isExplicitlyArchived", + }, + { + name: "archivedAt", + }, + { + name: "subject", + }, + { + name: "description", + }, + { + name: "note", + }, + { + name: "priorityId", + }, + { + name: "personByAuthorId", + }, + { + name: "singleTableItemByParentId", + }, + { + name: "priorityByPriorityId", + }, + { + name: "singleTableItemsByParentId", + }, + { + name: "singleTableItemsByParentIdList", + }, + { + name: "childTopicsByReturnType", + }, + { + name: "childTopicsByReturnTypeList", + }, + { + name: "singleTableItemRelationsByChildId", + }, + { + name: "singleTableItemRelationsByChildIdList", + }, + { + name: "singleTableItemRelationsByParentId", + }, + { + name: "singleTableItemRelationsByParentIdList", + }, + { + name: "singleTableItemRelationCompositePksByChildId", + }, + { + name: "singleTableItemRelationCompositePksByChildIdList", + }, + { + name: "singleTableItemRelationCompositePksByParentId", + }, + { + name: "singleTableItemRelationCompositePksByParentIdList", + }, + { + name: "rootTopic", + }, + ], + }, + topicType: { + fields: [ + { + name: "nodeId", + }, + { + name: "meaningOfLife", + }, + { + name: "topics", + }, + { + name: "topicsList", + }, + { + name: "id", + }, + { + name: "type", + }, + { + name: "parentId", + }, + { + name: "rootTopicId", + }, + { + name: "authorId", + }, + { + name: "position", + }, + { + name: "createdAt", + }, + { + name: "updatedAt", + }, + { + name: "isExplicitlyArchived", + }, + { + name: "archivedAt", + }, + { + name: "title", + }, + { + name: "personByAuthorId", + }, + { + name: "singleTableItemByParentId", + }, + { + name: "singleTableItemsByParentId", + }, + { + name: "singleTableItemsByParentIdList", + }, + { + name: "childTopicsByReturnType", + }, + { + name: "childTopicsByReturnTypeList", + }, + { + name: "singleTableItemRelationsByChildId", + }, + { + name: "singleTableItemRelationsByChildIdList", + }, + { + name: "singleTableItemRelationsByParentId", + }, + { + name: "singleTableItemRelationsByParentIdList", + }, + { + name: "singleTableItemRelationCompositePksByChildId", + }, + { + name: "singleTableItemRelationCompositePksByChildIdList", + }, + { + name: "singleTableItemRelationCompositePksByParentId", + }, + { + name: "singleTableItemRelationCompositePksByParentIdList", + }, + { + name: "rootTopic", + }, + ], + }, + dividerType: { + fields: [ + { + name: "nodeId", + }, + { + name: "meaningOfLife", + }, + { + name: "topics", + }, + { + name: "topicsList", + }, + { + name: "id", + }, + { + name: "type", + }, + { + name: "parentId", + }, + { + name: "rootTopicId", + }, + { + name: "authorId", + }, + { + name: "position", + }, + { + name: "createdAt", + }, + { + name: "updatedAt", + }, + { + name: "isExplicitlyArchived", + }, + { + name: "archivedAt", + }, + { + name: "title", + }, + { + name: "color", + }, + { + name: "personByAuthorId", + }, + { + name: "singleTableItemByParentId", + }, + { + name: "singleTableItemsByParentId", + }, + { + name: "singleTableItemsByParentIdList", + }, + { + name: "childTopicsByReturnType", + }, + { + name: "childTopicsByReturnTypeList", + }, + { + name: "singleTableItemRelationsByChildId", + }, + { + name: "singleTableItemRelationsByChildIdList", + }, + { + name: "singleTableItemRelationsByParentId", + }, + { + name: "singleTableItemRelationsByParentIdList", + }, + { + name: "singleTableItemRelationCompositePksByChildId", + }, + { + name: "singleTableItemRelationCompositePksByChildIdList", + }, + { + name: "singleTableItemRelationCompositePksByParentId", + }, + { + name: "singleTableItemRelationCompositePksByParentIdList", + }, + { + name: "rootTopic", + }, + ], + }, + allSingleTableItems: { + nodes: [ + { + id: 4, + type: "POST", + postOnly: "post only: Better planning", + }, + ], + }, +} diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.mermaid b/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.mermaid new file mode 100644 index 0000000000..788cc1d284 --- /dev/null +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.mermaid @@ -0,0 +1,59 @@ +%%{init: {'themeVariables': { 'fontSize': '12px'}}}%% +graph TD + classDef path fill:#eee,stroke:#000,color:#000 + classDef plan fill:#fff,stroke-width:1px,color:#000 + classDef itemplan fill:#fff,stroke-width:2px,color:#000 + classDef unbatchedplan fill:#dff,stroke-width:1px,color:#000 + classDef sideeffectplan fill:#fcc,stroke-width:2px,color:#000 + classDef bucket fill:#f6f6f6,color:#000,stroke-width:2px,text-align:left + + subgraph "Buckets for queries/polymorphic/apply-to-type-computed-column" + Bucket0("Bucket 0 (root)

1:
ᐳ: 6, 11, 12, 39, 7, 13, 15
2: PgSelect[10]
3: Connection[14]
4: ConnectionItems[17]"):::bucket + Bucket1("Bucket 1 (nullableBoundary)
Deps: 14, 17

ROOT Connectionᐸ10ᐳ[14]"):::bucket + Bucket3("Bucket 3 (listItem)

ROOT __Item{3}ᐸ17ᐳ[20]"):::bucket + Bucket4("Bucket 4 (polymorphic)
__typename: Lambda[26]
Deps: 21, 26, 22, 25"):::bucket + end + Bucket0 --> Bucket1 + Bucket1 --> Bucket3 + Bucket3 --> Bucket4 + + %% plan dependencies + __InputObject7{{"__InputObject[7∈0] ➊
More deps:
- Constantᐸ4ᐳ[39]
- Constantᐸundefinedᐳ[6]"}}:::plan + PgSelect10[["PgSelect[10∈0] ➊
ᐸsingle_table_itemsᐳ"]]:::plan + Object13{{"Object[13∈0] ➊
ᐸ{pgSettings,withPgClient}ᐳ"}}:::plan + ApplyInput15{{"ApplyInput[15∈0] ➊"}}:::plan + Object13 & ApplyInput15 --> PgSelect10 + Access11{{"Access[11∈0] ➊
ᐸ2.pgSettingsᐳ"}}:::plan + Access12{{"Access[12∈0] ➊
ᐸ2.withPgClientᐳ"}}:::plan + Access11 & Access12 --> Object13 + __Value2["__Value[2∈0] ➊
ᐸcontextᐳ"]:::plan + __Value2 --> Access11 + __Value2 --> Access12 + Connection14[["Connection[14∈0] ➊
ᐸ10ᐳ"]]:::plan + PgSelect10 --> Connection14 + __InputObject7 --> ApplyInput15 + ConnectionItems17[["ConnectionItems[17∈0] ➊"]]:::plan + Connection14 --> ConnectionItems17 + __Item20[/"__Item[20∈3]
ᐸ17ᐳ"\]:::itemplan + ConnectionItems17 ==> __Item20 + PgSelectSingle21{{"PgSelectSingle[21∈3]
ᐸsingle_table_itemsᐳ"}}:::plan + __Item20 --> PgSelectSingle21 + PgClassExpression22{{"PgClassExpression[22∈3]
ᐸ__single_t...ems__.”id”ᐳ"}}:::plan + PgSelectSingle21 --> PgClassExpression22 + PgClassExpression25{{"PgClassExpression[25∈3]
ᐸ__single_t...s__.”type”ᐳ"}}:::plan + PgSelectSingle21 --> PgClassExpression25 + Lambda26{{"Lambda[26∈3]
ᐸSingleTableItem_typeNameFromTypeᐳ"}}:::plan + PgClassExpression25 --> Lambda26 + PgClassExpression38{{"PgClassExpression[38∈4]
ᐸ”polymorph...e_items__)ᐳ
ᐳSingleTablePost"}}:::plan + PgClassExpression22 o--o PgClassExpression38 + + %% define steps + classDef bucket0 stroke:#696969 + class Bucket0,__Value2,__InputObject7,PgSelect10,Access11,Access12,Object13,Connection14,ApplyInput15,ConnectionItems17 bucket0 + classDef bucket1 stroke:#00bfff + class Bucket1 bucket1 + classDef bucket3 stroke:#ffa500 + class Bucket3,__Item20,PgSelectSingle21,PgClassExpression22,PgClassExpression25,Lambda26 bucket3 + classDef bucket4 stroke:#0000ff + class Bucket4,PgClassExpression38 bucket4 + diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.sql b/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.sql new file mode 100644 index 0000000000..a145bcfe6f --- /dev/null +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.sql @@ -0,0 +1,9 @@ +select + __single_table_items__."id"::text as "0", + __single_table_items__."type"::text as "1", + "polymorphic"."single_table_items_post_only"(__single_table_items__) as "2" +from "polymorphic"."single_table_items" as __single_table_items__ +where ( + __single_table_items__."id" = $1::"int4" +) +order by __single_table_items__."id" asc; \ No newline at end of file diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.test.graphql b/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.test.graphql new file mode 100644 index 0000000000..dd1ecac76f --- /dev/null +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.test.graphql @@ -0,0 +1,39 @@ +## expect(errors).toBeFalsy() +## expect(data.postType.fields.some((field) => field.name === "postOnly")).toBe(true) +## expect(data.interfaceType.fields.some((field) => field.name === "postOnly")).toBe(false) +## expect(data.topicType.fields.some((field) => field.name === "postOnly")).toBe(false) +## expect(data.dividerType.fields.some((field) => field.name === "postOnly")).toBe(false) +#> schema: ["polymorphic"] +#> simpleCollections: "both" + +{ + interfaceType: __type(name: "SingleTableItem") { + fields { + name + } + } + postType: __type(name: "SingleTablePost") { + fields { + name + } + } + topicType: __type(name: "SingleTableTopic") { + fields { + name + } + } + dividerType: __type(name: "SingleTableDivider") { + fields { + name + } + } + allSingleTableItems(condition: { id: 4 }) { + nodes { + id + type + ... on SingleTablePost { + postOnly + } + } + } +} diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.json5 b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.json5 index 76848a2e6d..4ac711688c 100644 --- a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.json5 +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.json5 @@ -10,6 +10,13 @@ }, }, }, + { + name: "postOnly", + type: { + name: "String", + ofType: null, + }, + }, { name: "meaningOfLife", type: { diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs index a32180f1e1..8bf3ddf74c 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs @@ -2725,6 +2725,7 @@ const gcp_applications_resourceOptionsConfig = { }, uniques: gcp_applicationsUniques }; +const single_table_items_post_onlyFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_post_only"); const single_table_items_meaning_of_lifeFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_meaning_of_life"); const custom_delete_relational_itemFunctionIdentifer = sql.identifier("polymorphic", "custom_delete_relational_item"); const relational_items_meaning_of_lifeFunctionIdentifer = sql.identifier("polymorphic", "relational_items_meaning_of_life"); @@ -3272,6 +3273,31 @@ const registryConfig = { }), aws_applications: aws_applications_resourceOptionsConfig, gcp_applications: gcp_applications_resourceOptionsConfig, + single_table_items_post_only: { + executor: executor, + name: "single_table_items_post_only", + identifier: "main.polymorphic.single_table_items_post_only(polymorphic.single_table_items)", + from(...args) { + return sql`${single_table_items_post_onlyFunctionIdentifer}(${sqlFromArgDigests(args)})`; + }, + parameters: [{ + name: "sti", + codec: singleTableItemsCodec + }], + codec: TYPES.text, + hasImplicitOrder: false, + extensions: { + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "single_table_items_post_only" + }, + tags: { + applyToType: "SingleTablePost" + } + }, + isUnique: true + }, single_table_items_meaning_of_life: { executor: executor, name: "single_table_items_meaning_of_life", @@ -4611,6 +4637,7 @@ const SingleTableItemRelationsOrderBy_CHILD_ID_DESCApply = queryBuilder => { direction: "DESC" }); }; +const resource_single_table_items_post_onlyPgResource = registry.pgResources["single_table_items_post_only"]; const SingleTablePost_priorityIdPlan = $record => { return $record.get("priority_id"); }; @@ -7057,6 +7084,7 @@ enum SingleTableItemRelationCompositePksOrderBy { } type SingleTablePost implements SingleTableItem { + postOnly: String meaningOfLife: Int """Reads and enables pagination through a set of \`SingleTableTopic\`.""" @@ -14065,6 +14093,9 @@ export const objects = { meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, parentId: SingleTableTopic_parentIdPlan, personByAuthorId: SingleTableTopic_personByAuthorIdPlan, + postOnly($in, args, _info) { + return scalarComputed(resource_single_table_items_post_onlyPgResource, $in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); + }, priorityByPriorityId: SingleTablePost_priorityByPriorityIdPlan, priorityId: SingleTablePost_priorityIdPlan, rootTopic: SingleTableTopic_rootTopicPlan, diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql index 1d9d218e79..ebcb757d00 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql @@ -5224,6 +5224,7 @@ type SingleTablePost implements SingleTableItem { """Reads a single `Person` that is related to this `SingleTableItem`.""" personByAuthorId: Person position: BigInt! + postOnly: String """Reads a single `Priority` that is related to this `SingleTableItem`.""" priorityByPriorityId: Priority diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs index 5e3b749e97..2bbb9ebac6 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs @@ -2738,6 +2738,7 @@ const gcp_applications_resourceOptionsConfig = { }, uniques: gcp_applicationsUniques }; +const single_table_items_post_onlyFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_post_only"); const single_table_items_meaning_of_lifeFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_meaning_of_life"); const custom_delete_relational_itemFunctionIdentifer = sql.identifier("polymorphic", "custom_delete_relational_item"); const relational_items_meaning_of_lifeFunctionIdentifer = sql.identifier("polymorphic", "relational_items_meaning_of_life"); @@ -3285,6 +3286,31 @@ const registryConfig = { }), aws_applications: aws_applications_resourceOptionsConfig, gcp_applications: gcp_applications_resourceOptionsConfig, + single_table_items_post_only: { + executor: executor, + name: "single_table_items_post_only", + identifier: "main.polymorphic.single_table_items_post_only(polymorphic.single_table_items)", + from(...args) { + return sql`${single_table_items_post_onlyFunctionIdentifer}(${sqlFromArgDigests(args)})`; + }, + parameters: [{ + name: "sti", + codec: singleTableItemsCodec + }], + codec: TYPES.text, + hasImplicitOrder: false, + extensions: { + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "single_table_items_post_only" + }, + tags: { + applyToType: "SingleTablePost" + } + }, + isUnique: true + }, single_table_items_meaning_of_life: { executor: executor, name: "single_table_items_meaning_of_life", @@ -5195,6 +5221,7 @@ const SingleTableItemRelationsOrderBy_CHILD_ID_DESCApply = queryBuilder => { direction: "DESC" }); }; +const resource_single_table_items_post_onlyPgResource = registry.pgResources["single_table_items_post_only"]; const SingleTablePost_priorityIdPlan = $record => { return $record.get("priority_id"); }; @@ -8248,6 +8275,7 @@ type SingleTablePost implements SingleTableItem & Node { A globally unique identifier. Can be used in various places throughout the system to identify this single value. """ nodeId: ID! + postOnly: String meaningOfLife: Int """Reads and enables pagination through a set of \`SingleTableTopic\`.""" @@ -19833,6 +19861,9 @@ export const objects = { }, parentId: SingleTableTopic_parentIdPlan, personByAuthorId: SingleTableTopic_personByAuthorIdPlan, + postOnly($in, args, _info) { + return scalarComputed(resource_single_table_items_post_onlyPgResource, $in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); + }, priorityByPriorityId: SingleTablePost_priorityByPriorityIdPlan, priorityId: SingleTablePost_priorityIdPlan, rootTopic: SingleTableTopic_rootTopicPlan, diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql index 03cdb157cb..50e70a4402 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql @@ -7915,6 +7915,7 @@ type SingleTablePost implements Node & SingleTableItem { """Reads a single `Person` that is related to this `SingleTableItem`.""" personByAuthorId: Person position: BigInt! + postOnly: String """Reads a single `Priority` that is related to this `SingleTableItem`.""" priorityByPriorityId: Priority diff --git a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs index 294d8935cc..db06d28938 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs @@ -2725,6 +2725,7 @@ const gcp_applications_resourceOptionsConfig = { }, uniques: gcp_applicationsUniques }; +const single_table_items_post_onlyFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_post_only"); const single_table_items_meaning_of_lifeFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_meaning_of_life"); const custom_delete_relational_itemFunctionIdentifer = sql.identifier("polymorphic", "custom_delete_relational_item"); const relational_items_meaning_of_lifeFunctionIdentifer = sql.identifier("polymorphic", "relational_items_meaning_of_life"); @@ -3272,6 +3273,31 @@ const registryConfig = { }), aws_applications: aws_applications_resourceOptionsConfig, gcp_applications: gcp_applications_resourceOptionsConfig, + single_table_items_post_only: { + executor: executor, + name: "single_table_items_post_only", + identifier: "main.polymorphic.single_table_items_post_only(polymorphic.single_table_items)", + from(...args) { + return sql`${single_table_items_post_onlyFunctionIdentifer}(${sqlFromArgDigests(args)})`; + }, + parameters: [{ + name: "sti", + codec: singleTableItemsCodec + }], + codec: TYPES.text, + hasImplicitOrder: false, + extensions: { + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "single_table_items_post_only" + }, + tags: { + applyToType: "SingleTablePost" + } + }, + isUnique: true + }, single_table_items_meaning_of_life: { executor: executor, name: "single_table_items_meaning_of_life", @@ -4850,6 +4876,7 @@ const SingleTableItemRelationsOrderBy_CHILD_ID_DESCApply = queryBuilder => { direction: "DESC" }); }; +const resource_single_table_items_post_onlyPgResource = registry.pgResources["single_table_items_post_only"]; const SingleTablePost_priorityIdPlan = $record => { return $record.get("priority_id"); }; @@ -7614,6 +7641,7 @@ enum SingleTableItemRelationCompositePksOrderBy { } type SingleTablePost implements SingleTableItem { + postOnly: String meaningOfLife: Int """Reads and enables pagination through a set of \`SingleTableTopic\`.""" @@ -17754,6 +17782,9 @@ export const objects = { meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, parentId: SingleTableTopic_parentIdPlan, personByAuthorId: SingleTableTopic_personByAuthorIdPlan, + postOnly($in, args, _info) { + return scalarComputed(resource_single_table_items_post_onlyPgResource, $in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); + }, priorityByPriorityId: SingleTablePost_priorityByPriorityIdPlan, priorityId: SingleTablePost_priorityIdPlan, rootTopic: SingleTableTopic_rootTopicPlan, diff --git a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql index ec0863a1cd..178403f699 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql @@ -7146,6 +7146,7 @@ type SingleTablePost implements SingleTableItem { """Reads a single `Person` that is related to this `SingleTableItem`.""" personByAuthorId: Person position: BigInt! + postOnly: String """Reads a single `Priority` that is related to this `SingleTableItem`.""" priorityByPriorityId: Priority diff --git a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs index afe362bef9..c6493a5d5e 100644 --- a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs @@ -2719,6 +2719,7 @@ const gcp_applications_resourceOptionsConfig = { }, uniques: gcp_applicationsUniques }; +const single_table_items_post_onlyFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_post_only"); const single_table_items_meaning_of_lifeFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_meaning_of_life"); const custom_delete_relational_itemFunctionIdentifer = sql.identifier("polymorphic", "custom_delete_relational_item"); const relational_items_meaning_of_lifeFunctionIdentifer = sql.identifier("polymorphic", "relational_items_meaning_of_life"); @@ -3266,6 +3267,31 @@ const registryConfig = { }), aws_applications: aws_applications_resourceOptionsConfig, gcp_applications: gcp_applications_resourceOptionsConfig, + single_table_items_post_only: { + executor: executor, + name: "single_table_items_post_only", + identifier: "main.polymorphic.single_table_items_post_only(polymorphic.single_table_items)", + from(...args) { + return sql`${single_table_items_post_onlyFunctionIdentifer}(${sqlFromArgDigests(args)})`; + }, + parameters: [{ + name: "sti", + codec: singleTableItemsCodec + }], + codec: TYPES.text, + hasImplicitOrder: false, + extensions: { + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "single_table_items_post_only" + }, + tags: { + applyToType: "SingleTablePost" + } + }, + isUnique: true + }, single_table_items_meaning_of_life: { executor: executor, name: "single_table_items_meaning_of_life", @@ -5290,6 +5316,7 @@ const SingleTableItemRelationOrderBy_CHILD_ID_DESCApply = queryBuilder => { direction: "DESC" }); }; +const resource_single_table_items_post_onlyPgResource = registry.pgResources["single_table_items_post_only"]; const SingleTablePost_priorityIdPlan = $record => { return $record.get("priority_id"); }; @@ -8302,6 +8329,7 @@ enum SingleTableItemRelationCompositePkOrderBy { } type SingleTablePost implements SingleTableItem { + postOnly: String meaningOfLife: Int """Reads and enables pagination through a set of \`SingleTableTopic\`.""" @@ -19736,6 +19764,9 @@ export const objects = { meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, parentId: SingleTableTopic_parentIdPlan, personByAuthorId: SingleTableTopic_personByAuthorIdPlan, + postOnly($in, args, _info) { + return scalarComputed(resource_single_table_items_post_onlyPgResource, $in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); + }, priorityByPriorityId: SingleTablePost_priorityByPriorityIdPlan, priorityId: SingleTablePost_priorityIdPlan, rootTopic: SingleTableTopic_rootTopicPlan, diff --git a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql index efa51cfa08..7f600215d7 100644 --- a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql @@ -8267,6 +8267,7 @@ type SingleTablePost implements SingleTableItem { """Reads a single `Person` that is related to this `SingleTableItem`.""" personByAuthorId: Person position: BigInt! + postOnly: String """Reads a single `Priority` that is related to this `SingleTableItem`.""" priorityByPriorityId: Priority diff --git a/postgraphile/website/postgraphile/smart-tags.md b/postgraphile/website/postgraphile/smart-tags.md index c89e00071c..89572d8782 100644 --- a/postgraphile/website/postgraphile/smart-tags.md +++ b/postgraphile/website/postgraphile/smart-tags.md @@ -357,6 +357,46 @@ may occur. ::: +## @applyToType + +Applies to: + +- Computed Column functions + +Details the _named_ GraphQL type that should receive the computed column field. +This is useful when a computed column function is defined against a PostgreSQL +polymorphic table type, but the field only makes sense on one concrete +(monomorphic) GraphQL type that implements the polymorphic interface. + +When `@applyToType` is set, PostGraphile only generates the computed column on +the named type. The field is not added to the polymorphic interface or to the +other concrete types that implement it. + +The value must be the GraphQL type name, after inflection and smart tags have +been applied. If no generated type has this exact name, the computed column is +not generated. + +```json5 title="postgraphile.tags.json5" +{ + version: 1, + config: { + procedure: { + single_table_items_post_only: { + tags: { + applyToType: "SingleTablePost", + }, + }, + }, + }, +} +``` + +```sql +comment on function polymorphic.single_table_items_post_only( + polymorphic.single_table_items +) is E'@applyToType SingleTablePost'; +``` + ## @resultFieldName Applies to: From 8e511d040071c072eb29a2015aa8cd42c12f0c12 Mon Sep 17 00:00:00 2001 From: tsnobip Date: Mon, 8 Jun 2026 17:14:23 +0200 Subject: [PATCH 5/6] support multiple `@applyToType` smart tags --- graphile-build/graphile-build-pg/src/index.ts | 4 +-- .../src/plugins/PgCustomTypeFieldPlugin.ts | 19 +++++++++-- .../__tests__/kitchen-sink-schema.sql | 13 +++++++ .../apply-to-type-computed-column.json5 | 7 ++++ .../apply-to-type-computed-column.mermaid | 8 +++-- .../apply-to-type-computed-column.sql | 3 +- ...apply-to-type-computed-column.test.graphql | 5 +++ .../return-type-computed-column-setof.json5 | 7 ++++ .../polymorphic-auto-add-types.1.export.mjs | 34 +++++++++++++++++++ .../v4/polymorphic-auto-add-types.1.graphql | 2 ++ .../schema/v4/polymorphic.1.export.mjs | 34 +++++++++++++++++++ .../__tests__/schema/v4/polymorphic.1.graphql | 2 ++ .../skipNodePlugin.polymorphic.1.export.mjs | 34 +++++++++++++++++++ .../v4/skipNodePlugin.polymorphic.1.graphql | 2 ++ .../skipNodePlugin.polymorphic.1.export.mjs | 34 +++++++++++++++++++ .../v5/skipNodePlugin.polymorphic.1.graphql | 2 ++ .../website/postgraphile/smart-tags.md | 30 +++++++++++----- 17 files changed, 222 insertions(+), 18 deletions(-) diff --git a/graphile-build/graphile-build-pg/src/index.ts b/graphile-build/graphile-build-pg/src/index.ts index b29ea501f0..cbff6e17fa 100644 --- a/graphile-build/graphile-build-pg/src/index.ts +++ b/graphile-build/graphile-build-pg/src/index.ts @@ -62,8 +62,8 @@ declare global { nodeIdCodec: string; /** For functions returning polymorphic type, which type to choose? */ returnType: string; - /** For computed attribute functions, which GraphQL type should receive this field? */ - applyToType: string; + /** For computed attribute functions, which GraphQL type(s) should receive this field? */ + applyToType: string | string[]; /** For enum tables; we shouldn't expose these through GraphQL */ enum: string | true; diff --git a/graphile-build/graphile-build-pg/src/plugins/PgCustomTypeFieldPlugin.ts b/graphile-build/graphile-build-pg/src/plugins/PgCustomTypeFieldPlugin.ts index 9851591c81..f37bae6792 100644 --- a/graphile-build/graphile-build-pg/src/plugins/PgCustomTypeFieldPlugin.ts +++ b/graphile-build/graphile-build-pg/src/plugins/PgCustomTypeFieldPlugin.ts @@ -72,6 +72,17 @@ const $$rootQuery = Symbol("PgCustomTypeFieldPluginRootQuerySources"); const $$rootMutation = Symbol("PgCustomTypeFieldPluginRootMutationSources"); const $$computed = Symbol("PgCustomTypeFieldPluginComputedSources"); +function tagToStrings( + tag: undefined | null | boolean | string | (string | boolean)[], +): string[] { + if (!tag || (Array.isArray(tag) && tag.length === 0)) { + return []; + } + return (Array.isArray(tag) ? tag : [tag]).flatMap((entry) => + typeof entry === "string" ? [entry] : [], + ); +} + declare global { namespace GraphileConfig { interface Plugins { @@ -1158,12 +1169,14 @@ function modFields( return procSources.reduce( (memo, resource) => build.recoverable(memo, () => { - const applyToType = tagToString(resource.extensions?.tags?.applyToType); + const applyToTypes = tagToStrings( + resource.extensions?.tags?.applyToType, + ); const shouldSkipForApplyToType = isRootQuery || isRootMutation ? false - : applyToType - ? applyToType !== SelfName + : applyToTypes.length > 0 + ? !applyToTypes.includes(SelfName) : false; if (shouldSkipForApplyToType) { return memo; diff --git a/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql b/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql index 3a58b4e517..38618da269 100644 --- a/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql +++ b/postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql @@ -1450,6 +1450,19 @@ comment on function polymorphic.single_table_items_post_only( polymorphic.single_table_items ) is '@applyToType SingleTablePost'; +create function polymorphic.single_table_items_post_and_divider_only( + sti polymorphic.single_table_items +) +returns text as $$ +select 'post or divider only: ' || sti.title; +$$ language sql stable; +comment on function polymorphic.single_table_items_post_and_divider_only( + polymorphic.single_table_items +) is $$ + @applyToType SingleTablePost + @applyToType SingleTableDivider + $$; + create function polymorphic.all_single_tables () returns setof polymorphic.single_table_items as $$ select * from polymorphic.single_table_items diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.json5 b/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.json5 index 12f7fa96e2..1230e51b43 100644 --- a/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.json5 +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.json5 @@ -86,6 +86,9 @@ { name: "nodeId", }, + { + name: "postAndDividerOnly", + }, { name: "postOnly", }, @@ -289,6 +292,9 @@ { name: "nodeId", }, + { + name: "postAndDividerOnly", + }, { name: "meaningOfLife", }, @@ -387,6 +393,7 @@ id: 4, type: "POST", postOnly: "post only: Better planning", + postAndDividerOnly: "post or divider only: Better planning", }, ], }, diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.mermaid b/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.mermaid index 788cc1d284..a0dfdfe7da 100644 --- a/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.mermaid +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.mermaid @@ -8,7 +8,7 @@ graph TD classDef bucket fill:#f6f6f6,color:#000,stroke-width:2px,text-align:left subgraph "Buckets for queries/polymorphic/apply-to-type-computed-column" - Bucket0("Bucket 0 (root)

1:
ᐳ: 6, 11, 12, 39, 7, 13, 15
2: PgSelect[10]
3: Connection[14]
4: ConnectionItems[17]"):::bucket + Bucket0("Bucket 0 (root)

1:
ᐳ: 6, 11, 12, 40, 7, 13, 15
2: PgSelect[10]
3: Connection[14]
4: ConnectionItems[17]"):::bucket Bucket1("Bucket 1 (nullableBoundary)
Deps: 14, 17

ROOT Connectionᐸ10ᐳ[14]"):::bucket Bucket3("Bucket 3 (listItem)

ROOT __Item{3}ᐸ17ᐳ[20]"):::bucket Bucket4("Bucket 4 (polymorphic)
__typename: Lambda[26]
Deps: 21, 26, 22, 25"):::bucket @@ -18,7 +18,7 @@ graph TD Bucket3 --> Bucket4 %% plan dependencies - __InputObject7{{"__InputObject[7∈0] ➊
More deps:
- Constantᐸ4ᐳ[39]
- Constantᐸundefinedᐳ[6]"}}:::plan + __InputObject7{{"__InputObject[7∈0] ➊
More deps:
- Constantᐸ4ᐳ[40]
- Constantᐸundefinedᐳ[6]"}}:::plan PgSelect10[["PgSelect[10∈0] ➊
ᐸsingle_table_itemsᐳ"]]:::plan Object13{{"Object[13∈0] ➊
ᐸ{pgSettings,withPgClient}ᐳ"}}:::plan ApplyInput15{{"ApplyInput[15∈0] ➊"}}:::plan @@ -46,6 +46,8 @@ graph TD PgClassExpression25 --> Lambda26 PgClassExpression38{{"PgClassExpression[38∈4]
ᐸ”polymorph...e_items__)ᐳ
ᐳSingleTablePost"}}:::plan PgClassExpression22 o--o PgClassExpression38 + PgClassExpression39{{"PgClassExpression[39∈4]
ᐸ”polymorph...e_items__)ᐳ
ᐳSingleTablePost"}}:::plan + PgClassExpression38 o--o PgClassExpression39 %% define steps classDef bucket0 stroke:#696969 @@ -55,5 +57,5 @@ graph TD classDef bucket3 stroke:#ffa500 class Bucket3,__Item20,PgSelectSingle21,PgClassExpression22,PgClassExpression25,Lambda26 bucket3 classDef bucket4 stroke:#0000ff - class Bucket4,PgClassExpression38 bucket4 + class Bucket4,PgClassExpression38,PgClassExpression39 bucket4 diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.sql b/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.sql index a145bcfe6f..88ad89b21e 100644 --- a/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.sql +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.sql @@ -1,7 +1,8 @@ select __single_table_items__."id"::text as "0", __single_table_items__."type"::text as "1", - "polymorphic"."single_table_items_post_only"(__single_table_items__) as "2" + "polymorphic"."single_table_items_post_only"(__single_table_items__) as "2", + "polymorphic"."single_table_items_post_and_divider_only"(__single_table_items__) as "3" from "polymorphic"."single_table_items" as __single_table_items__ where ( __single_table_items__."id" = $1::"int4" diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.test.graphql b/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.test.graphql index dd1ecac76f..8aa35af4f1 100644 --- a/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.test.graphql +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/apply-to-type-computed-column.test.graphql @@ -1,8 +1,12 @@ ## expect(errors).toBeFalsy() ## expect(data.postType.fields.some((field) => field.name === "postOnly")).toBe(true) +## expect(data.postType.fields.some((field) => field.name === "postAndDividerOnly")).toBe(true) ## expect(data.interfaceType.fields.some((field) => field.name === "postOnly")).toBe(false) +## expect(data.interfaceType.fields.some((field) => field.name === "postAndDividerOnly")).toBe(false) ## expect(data.topicType.fields.some((field) => field.name === "postOnly")).toBe(false) +## expect(data.topicType.fields.some((field) => field.name === "postAndDividerOnly")).toBe(false) ## expect(data.dividerType.fields.some((field) => field.name === "postOnly")).toBe(false) +## expect(data.dividerType.fields.some((field) => field.name === "postAndDividerOnly")).toBe(true) #> schema: ["polymorphic"] #> simpleCollections: "both" @@ -33,6 +37,7 @@ type ... on SingleTablePost { postOnly + postAndDividerOnly } } } diff --git a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.json5 b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.json5 index 4ac711688c..44132e5290 100644 --- a/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.json5 +++ b/postgraphile/postgraphile/__tests__/queries/polymorphic/return-type-computed-column-setof.json5 @@ -10,6 +10,13 @@ }, }, }, + { + name: "postAndDividerOnly", + type: { + name: "String", + ofType: null, + }, + }, { name: "postOnly", type: { diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs index 8bf3ddf74c..0cf4c23d26 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.export.mjs @@ -2725,6 +2725,7 @@ const gcp_applications_resourceOptionsConfig = { }, uniques: gcp_applicationsUniques }; +const single_table_items_post_and_divider_onlyFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_post_and_divider_only"); const single_table_items_post_onlyFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_post_only"); const single_table_items_meaning_of_lifeFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_meaning_of_life"); const custom_delete_relational_itemFunctionIdentifer = sql.identifier("polymorphic", "custom_delete_relational_item"); @@ -3273,6 +3274,31 @@ const registryConfig = { }), aws_applications: aws_applications_resourceOptionsConfig, gcp_applications: gcp_applications_resourceOptionsConfig, + single_table_items_post_and_divider_only: { + executor: executor, + name: "single_table_items_post_and_divider_only", + identifier: "main.polymorphic.single_table_items_post_and_divider_only(polymorphic.single_table_items)", + from(...args) { + return sql`${single_table_items_post_and_divider_onlyFunctionIdentifer}(${sqlFromArgDigests(args)})`; + }, + parameters: [{ + name: "sti", + codec: singleTableItemsCodec + }], + codec: TYPES.text, + hasImplicitOrder: false, + extensions: { + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "single_table_items_post_and_divider_only" + }, + tags: { + applyToType: ["SingleTablePost", "SingleTableDivider"] + } + }, + isUnique: true + }, single_table_items_post_only: { executor: executor, name: "single_table_items_post_only", @@ -4637,6 +4663,10 @@ const SingleTableItemRelationsOrderBy_CHILD_ID_DESCApply = queryBuilder => { direction: "DESC" }); }; +const resource_single_table_items_post_and_divider_onlyPgResource = registry.pgResources["single_table_items_post_and_divider_only"]; +const single_table_items_post_and_divider_only_getSelectPlanFromParentAndArgs = ($in, args, _info) => { + return scalarComputed(resource_single_table_items_post_and_divider_onlyPgResource, $in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); +}; const resource_single_table_items_post_onlyPgResource = registry.pgResources["single_table_items_post_only"]; const SingleTablePost_priorityIdPlan = $record => { return $record.get("priority_id"); @@ -7084,6 +7114,7 @@ enum SingleTableItemRelationCompositePksOrderBy { } type SingleTablePost implements SingleTableItem { + postAndDividerOnly: String postOnly: String meaningOfLife: Int @@ -7348,6 +7379,7 @@ type Priority { } type SingleTableDivider implements SingleTableItem { + postAndDividerOnly: String meaningOfLife: Int """Reads and enables pagination through a set of \`SingleTableTopic\`.""" @@ -13947,6 +13979,7 @@ export const objects = { meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, parentId: SingleTableTopic_parentIdPlan, personByAuthorId: SingleTableTopic_personByAuthorIdPlan, + postAndDividerOnly: single_table_items_post_and_divider_only_getSelectPlanFromParentAndArgs, rootTopic: SingleTableTopic_rootTopicPlan, rootTopicId: SingleTableTopic_rootTopicIdPlan, singleTableItemByParentId: SingleTableTopic_singleTableItemByParentIdPlan, @@ -14093,6 +14126,7 @@ export const objects = { meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, parentId: SingleTableTopic_parentIdPlan, personByAuthorId: SingleTableTopic_personByAuthorIdPlan, + postAndDividerOnly: single_table_items_post_and_divider_only_getSelectPlanFromParentAndArgs, postOnly($in, args, _info) { return scalarComputed(resource_single_table_items_post_onlyPgResource, $in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); }, diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql index ebcb757d00..4373951b13 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic-auto-add-types.1.graphql @@ -4610,6 +4610,7 @@ type SingleTableDivider implements SingleTableItem { """Reads a single `Person` that is related to this `SingleTableItem`.""" personByAuthorId: Person position: BigInt! + postAndDividerOnly: String """ Reads a single `SingleTableTopic` that is related to this `SingleTableDivider`. @@ -5224,6 +5225,7 @@ type SingleTablePost implements SingleTableItem { """Reads a single `Person` that is related to this `SingleTableItem`.""" personByAuthorId: Person position: BigInt! + postAndDividerOnly: String postOnly: String """Reads a single `Priority` that is related to this `SingleTableItem`.""" diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs index 2bbb9ebac6..3535615505 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.export.mjs @@ -2738,6 +2738,7 @@ const gcp_applications_resourceOptionsConfig = { }, uniques: gcp_applicationsUniques }; +const single_table_items_post_and_divider_onlyFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_post_and_divider_only"); const single_table_items_post_onlyFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_post_only"); const single_table_items_meaning_of_lifeFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_meaning_of_life"); const custom_delete_relational_itemFunctionIdentifer = sql.identifier("polymorphic", "custom_delete_relational_item"); @@ -3286,6 +3287,31 @@ const registryConfig = { }), aws_applications: aws_applications_resourceOptionsConfig, gcp_applications: gcp_applications_resourceOptionsConfig, + single_table_items_post_and_divider_only: { + executor: executor, + name: "single_table_items_post_and_divider_only", + identifier: "main.polymorphic.single_table_items_post_and_divider_only(polymorphic.single_table_items)", + from(...args) { + return sql`${single_table_items_post_and_divider_onlyFunctionIdentifer}(${sqlFromArgDigests(args)})`; + }, + parameters: [{ + name: "sti", + codec: singleTableItemsCodec + }], + codec: TYPES.text, + hasImplicitOrder: false, + extensions: { + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "single_table_items_post_and_divider_only" + }, + tags: { + applyToType: ["SingleTablePost", "SingleTableDivider"] + } + }, + isUnique: true + }, single_table_items_post_only: { executor: executor, name: "single_table_items_post_only", @@ -5221,6 +5247,10 @@ const SingleTableItemRelationsOrderBy_CHILD_ID_DESCApply = queryBuilder => { direction: "DESC" }); }; +const resource_single_table_items_post_and_divider_onlyPgResource = registry.pgResources["single_table_items_post_and_divider_only"]; +const single_table_items_post_and_divider_only_getSelectPlanFromParentAndArgs = ($in, args, _info) => { + return scalarComputed(resource_single_table_items_post_and_divider_onlyPgResource, $in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); +}; const resource_single_table_items_post_onlyPgResource = registry.pgResources["single_table_items_post_only"]; const SingleTablePost_priorityIdPlan = $record => { return $record.get("priority_id"); @@ -8275,6 +8305,7 @@ type SingleTablePost implements SingleTableItem & Node { A globally unique identifier. Can be used in various places throughout the system to identify this single value. """ nodeId: ID! + postAndDividerOnly: String postOnly: String meaningOfLife: Int @@ -8547,6 +8578,7 @@ type SingleTableDivider implements SingleTableItem & Node { A globally unique identifier. Can be used in various places throughout the system to identify this single value. """ nodeId: ID! + postAndDividerOnly: String meaningOfLife: Int """Reads and enables pagination through a set of \`SingleTableTopic\`.""" @@ -19703,6 +19735,7 @@ export const objects = { }, parentId: SingleTableTopic_parentIdPlan, personByAuthorId: SingleTableTopic_personByAuthorIdPlan, + postAndDividerOnly: single_table_items_post_and_divider_only_getSelectPlanFromParentAndArgs, rootTopic: SingleTableTopic_rootTopicPlan, rootTopicId: SingleTableTopic_rootTopicIdPlan, singleTableItemByParentId: SingleTableTopic_singleTableItemByParentIdPlan, @@ -19861,6 +19894,7 @@ export const objects = { }, parentId: SingleTableTopic_parentIdPlan, personByAuthorId: SingleTableTopic_personByAuthorIdPlan, + postAndDividerOnly: single_table_items_post_and_divider_only_getSelectPlanFromParentAndArgs, postOnly($in, args, _info) { return scalarComputed(resource_single_table_items_post_onlyPgResource, $in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); }, diff --git a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql index 50e70a4402..f6435f1c60 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/polymorphic.1.graphql @@ -7251,6 +7251,7 @@ type SingleTableDivider implements Node & SingleTableItem { """Reads a single `Person` that is related to this `SingleTableItem`.""" personByAuthorId: Person position: BigInt! + postAndDividerOnly: String """ Reads a single `SingleTableTopic` that is related to this `SingleTableDivider`. @@ -7915,6 +7916,7 @@ type SingleTablePost implements Node & SingleTableItem { """Reads a single `Person` that is related to this `SingleTableItem`.""" personByAuthorId: Person position: BigInt! + postAndDividerOnly: String postOnly: String """Reads a single `Priority` that is related to this `SingleTableItem`.""" diff --git a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs index db06d28938..10d7d63043 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.export.mjs @@ -2725,6 +2725,7 @@ const gcp_applications_resourceOptionsConfig = { }, uniques: gcp_applicationsUniques }; +const single_table_items_post_and_divider_onlyFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_post_and_divider_only"); const single_table_items_post_onlyFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_post_only"); const single_table_items_meaning_of_lifeFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_meaning_of_life"); const custom_delete_relational_itemFunctionIdentifer = sql.identifier("polymorphic", "custom_delete_relational_item"); @@ -3273,6 +3274,31 @@ const registryConfig = { }), aws_applications: aws_applications_resourceOptionsConfig, gcp_applications: gcp_applications_resourceOptionsConfig, + single_table_items_post_and_divider_only: { + executor: executor, + name: "single_table_items_post_and_divider_only", + identifier: "main.polymorphic.single_table_items_post_and_divider_only(polymorphic.single_table_items)", + from(...args) { + return sql`${single_table_items_post_and_divider_onlyFunctionIdentifer}(${sqlFromArgDigests(args)})`; + }, + parameters: [{ + name: "sti", + codec: singleTableItemsCodec + }], + codec: TYPES.text, + hasImplicitOrder: false, + extensions: { + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "single_table_items_post_and_divider_only" + }, + tags: { + applyToType: ["SingleTablePost", "SingleTableDivider"] + } + }, + isUnique: true + }, single_table_items_post_only: { executor: executor, name: "single_table_items_post_only", @@ -4876,6 +4902,10 @@ const SingleTableItemRelationsOrderBy_CHILD_ID_DESCApply = queryBuilder => { direction: "DESC" }); }; +const resource_single_table_items_post_and_divider_onlyPgResource = registry.pgResources["single_table_items_post_and_divider_only"]; +const single_table_items_post_and_divider_only_getSelectPlanFromParentAndArgs = ($in, args, _info) => { + return scalarComputed(resource_single_table_items_post_and_divider_onlyPgResource, $in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); +}; const resource_single_table_items_post_onlyPgResource = registry.pgResources["single_table_items_post_only"]; const SingleTablePost_priorityIdPlan = $record => { return $record.get("priority_id"); @@ -7641,6 +7671,7 @@ enum SingleTableItemRelationCompositePksOrderBy { } type SingleTablePost implements SingleTableItem { + postAndDividerOnly: String postOnly: String meaningOfLife: Int @@ -7905,6 +7936,7 @@ type Priority { } type SingleTableDivider implements SingleTableItem { + postAndDividerOnly: String meaningOfLife: Int """Reads and enables pagination through a set of \`SingleTableTopic\`.""" @@ -17636,6 +17668,7 @@ export const objects = { meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, parentId: SingleTableTopic_parentIdPlan, personByAuthorId: SingleTableTopic_personByAuthorIdPlan, + postAndDividerOnly: single_table_items_post_and_divider_only_getSelectPlanFromParentAndArgs, rootTopic: SingleTableTopic_rootTopicPlan, rootTopicId: SingleTableTopic_rootTopicIdPlan, singleTableItemByParentId: SingleTableTopic_singleTableItemByParentIdPlan, @@ -17782,6 +17815,7 @@ export const objects = { meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, parentId: SingleTableTopic_parentIdPlan, personByAuthorId: SingleTableTopic_personByAuthorIdPlan, + postAndDividerOnly: single_table_items_post_and_divider_only_getSelectPlanFromParentAndArgs, postOnly($in, args, _info) { return scalarComputed(resource_single_table_items_post_onlyPgResource, $in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); }, diff --git a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql index 178403f699..b54d7b05ca 100644 --- a/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v4/skipNodePlugin.polymorphic.1.graphql @@ -6502,6 +6502,7 @@ type SingleTableDivider implements SingleTableItem { """Reads a single `Person` that is related to this `SingleTableItem`.""" personByAuthorId: Person position: BigInt! + postAndDividerOnly: String """ Reads a single `SingleTableTopic` that is related to this `SingleTableDivider`. @@ -7146,6 +7147,7 @@ type SingleTablePost implements SingleTableItem { """Reads a single `Person` that is related to this `SingleTableItem`.""" personByAuthorId: Person position: BigInt! + postAndDividerOnly: String postOnly: String """Reads a single `Priority` that is related to this `SingleTableItem`.""" diff --git a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs index c6493a5d5e..58752908bc 100644 --- a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs +++ b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.export.mjs @@ -2719,6 +2719,7 @@ const gcp_applications_resourceOptionsConfig = { }, uniques: gcp_applicationsUniques }; +const single_table_items_post_and_divider_onlyFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_post_and_divider_only"); const single_table_items_post_onlyFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_post_only"); const single_table_items_meaning_of_lifeFunctionIdentifer = sql.identifier("polymorphic", "single_table_items_meaning_of_life"); const custom_delete_relational_itemFunctionIdentifer = sql.identifier("polymorphic", "custom_delete_relational_item"); @@ -3267,6 +3268,31 @@ const registryConfig = { }), aws_applications: aws_applications_resourceOptionsConfig, gcp_applications: gcp_applications_resourceOptionsConfig, + single_table_items_post_and_divider_only: { + executor: executor, + name: "single_table_items_post_and_divider_only", + identifier: "main.polymorphic.single_table_items_post_and_divider_only(polymorphic.single_table_items)", + from(...args) { + return sql`${single_table_items_post_and_divider_onlyFunctionIdentifer}(${sqlFromArgDigests(args)})`; + }, + parameters: [{ + name: "sti", + codec: singleTableItemsCodec + }], + codec: TYPES.text, + hasImplicitOrder: false, + extensions: { + pg: { + serviceName: "main", + schemaName: "polymorphic", + name: "single_table_items_post_and_divider_only" + }, + tags: { + applyToType: ["SingleTablePost", "SingleTableDivider"] + } + }, + isUnique: true + }, single_table_items_post_only: { executor: executor, name: "single_table_items_post_only", @@ -5316,6 +5342,10 @@ const SingleTableItemRelationOrderBy_CHILD_ID_DESCApply = queryBuilder => { direction: "DESC" }); }; +const resource_single_table_items_post_and_divider_onlyPgResource = registry.pgResources["single_table_items_post_and_divider_only"]; +const single_table_items_post_and_divider_only_getSelectPlanFromParentAndArgs = ($in, args, _info) => { + return scalarComputed(resource_single_table_items_post_and_divider_onlyPgResource, $in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); +}; const resource_single_table_items_post_onlyPgResource = registry.pgResources["single_table_items_post_only"]; const SingleTablePost_priorityIdPlan = $record => { return $record.get("priority_id"); @@ -8329,6 +8359,7 @@ enum SingleTableItemRelationCompositePkOrderBy { } type SingleTablePost implements SingleTableItem { + postAndDividerOnly: String postOnly: String meaningOfLife: Int @@ -8587,6 +8618,7 @@ type Priority { } type SingleTableDivider implements SingleTableItem { + postAndDividerOnly: String meaningOfLife: Int """Reads and enables pagination through a set of \`SingleTableTopic\`.""" @@ -19618,6 +19650,7 @@ export const objects = { meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, parentId: SingleTableTopic_parentIdPlan, personByAuthorId: SingleTableTopic_personByAuthorIdPlan, + postAndDividerOnly: single_table_items_post_and_divider_only_getSelectPlanFromParentAndArgs, rootTopic: SingleTableTopic_rootTopicPlan, rootTopicId: SingleTableTopic_rootTopicIdPlan, rowId: SingleTableTopic_rowIdPlan, @@ -19764,6 +19797,7 @@ export const objects = { meaningOfLife: single_table_items_meaning_of_life_getSelectPlanFromParentAndArgs, parentId: SingleTableTopic_parentIdPlan, personByAuthorId: SingleTableTopic_personByAuthorIdPlan, + postAndDividerOnly: single_table_items_post_and_divider_only_getSelectPlanFromParentAndArgs, postOnly($in, args, _info) { return scalarComputed(resource_single_table_items_post_onlyPgResource, $in, makeArgs_first_party_vulnerabilities_cvss_score_int(args)); }, diff --git a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql index 7f600215d7..3068c4725a 100644 --- a/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql +++ b/postgraphile/postgraphile/__tests__/schema/v5/skipNodePlugin.polymorphic.1.graphql @@ -7631,6 +7631,7 @@ type SingleTableDivider implements SingleTableItem { """Reads a single `Person` that is related to this `SingleTableItem`.""" personByAuthorId: Person position: BigInt! + postAndDividerOnly: String """ Reads a single `SingleTableTopic` that is related to this `SingleTableDivider`. @@ -8267,6 +8268,7 @@ type SingleTablePost implements SingleTableItem { """Reads a single `Person` that is related to this `SingleTableItem`.""" personByAuthorId: Person position: BigInt! + postAndDividerOnly: String postOnly: String """Reads a single `Priority` that is related to this `SingleTableItem`.""" diff --git a/postgraphile/website/postgraphile/smart-tags.md b/postgraphile/website/postgraphile/smart-tags.md index 89572d8782..7ef6b06869 100644 --- a/postgraphile/website/postgraphile/smart-tags.md +++ b/postgraphile/website/postgraphile/smart-tags.md @@ -363,18 +363,19 @@ Applies to: - Computed Column functions -Details the _named_ GraphQL type that should receive the computed column field. -This is useful when a computed column function is defined against a PostgreSQL -polymorphic table type, but the field only makes sense on one concrete -(monomorphic) GraphQL type that implements the polymorphic interface. +Details the _named_ GraphQL type, or types, that should receive the computed +column field. This is useful when a computed column function is defined against +a PostgreSQL polymorphic table type, but the field only makes sense on one or +more concrete (monomorphic) GraphQL types that implement the polymorphic +interface. When `@applyToType` is set, PostGraphile only generates the computed column on -the named type. The field is not added to the polymorphic interface or to the -other concrete types that implement it. +the named type or types. The field is not added to the polymorphic interface or +to the other concrete types that implement it. -The value must be the GraphQL type name, after inflection and smart tags have -been applied. If no generated type has this exact name, the computed column is -not generated. +Each value must be a GraphQL type name, after inflection and smart tags have +been applied. If no generated type has a matching name, the computed column is +not generated for that value. ```json5 title="postgraphile.tags.json5" { @@ -397,6 +398,17 @@ comment on function polymorphic.single_table_items_post_only( ) is E'@applyToType SingleTablePost'; ``` +To apply the computed column to multiple types, repeat the smart tag: + +```sql +comment on function polymorphic.single_table_items_post_and_divider_only( + polymorphic.single_table_items +) is $$ + @applyToType SingleTablePost + @applyToType SingleTableDivider + $$; +``` + ## @resultFieldName Applies to: From ba63844c62a49d2a73fa16920107dc3b63bf107d Mon Sep 17 00:00:00 2001 From: tsnobip Date: Mon, 8 Jun 2026 17:13:51 +0200 Subject: [PATCH 6/6] docs(changeset): improve smart tags for polymorphic types --- .changeset/strict-apes-bow.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .changeset/strict-apes-bow.md diff --git a/.changeset/strict-apes-bow.md b/.changeset/strict-apes-bow.md new file mode 100644 index 0000000000..5624362d76 --- /dev/null +++ b/.changeset/strict-apes-bow.md @@ -0,0 +1,12 @@ +--- +"graphile-build-pg": minor +--- + +improve smart tags for polymorphic types + +- fix @returnType for functions returning setof (for lists and connections) +- support @returnType for foreign key constraints +- add @foreignReturnType for the backward relation of a foreign key constraint +- add @applyToType for computed columns, so a computed column defined on a + polymorphic PostgreSQL table can be exposed only on a specific concrete + GraphQL type.