From 9dcb3e03c94e87b8a3e98703b083d9e8f26f2cb0 Mon Sep 17 00:00:00 2001 From: Abhimanyu Singh Gaur <12651351+abhimanyusinghgaur@users.noreply.github.com> Date: Wed, 16 Sep 2020 12:24:19 +0530 Subject: [PATCH] fix(GraphQL): Generate correct schema when no orderable field in a type (#6456) Fixes GRAPHQL-650 It was introduced after #6392. (cherry picked from commit 8e4d1216167c3ce345d955bae3d7d1d69cb27593) --- graphql/schema/gqlschema.go | 6 +- .../input/type-without-orderables.graphql | 6 + .../output/type-without-orderables.graphql | 235 ++++++++++++++++++ 3 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 graphql/schema/testdata/schemagen/input/type-without-orderables.graphql create mode 100644 graphql/schema/testdata/schemagen/output/type-without-orderables.graphql diff --git a/graphql/schema/gqlschema.go b/graphql/schema/gqlschema.go index 48790002775..148e14a7258 100644 --- a/graphql/schema/gqlschema.go +++ b/graphql/schema/gqlschema.go @@ -834,7 +834,11 @@ func hasFilterable(defn *ast.Definition) bool { func hasOrderables(defn *ast.Definition) bool { return fieldAny(defn.Fields, - func(fld *ast.FieldDefinition) bool { return orderable[fld.Type.Name()] }) + func(fld *ast.FieldDefinition) bool { + // lists can't be ordered and NamedType will be empty for lists, + // so it will return false for list fields + return orderable[fld.Type.NamedType] + }) } func hasID(defn *ast.Definition) bool { diff --git a/graphql/schema/testdata/schemagen/input/type-without-orderables.graphql b/graphql/schema/testdata/schemagen/input/type-without-orderables.graphql new file mode 100644 index 00000000000..773242e89f6 --- /dev/null +++ b/graphql/schema/testdata/schemagen/input/type-without-orderables.graphql @@ -0,0 +1,6 @@ +type Data { + id: ID! + intList: [Int] + stringList: [String] + metaData: Data +} \ No newline at end of file diff --git a/graphql/schema/testdata/schemagen/output/type-without-orderables.graphql b/graphql/schema/testdata/schemagen/output/type-without-orderables.graphql new file mode 100644 index 00000000000..f361a23b0cd --- /dev/null +++ b/graphql/schema/testdata/schemagen/output/type-without-orderables.graphql @@ -0,0 +1,235 @@ +####################### +# Input Schema +####################### + +type Data { + id: ID! + intList: [Int] + stringList: [String] + metaData(filter: DataFilter): Data +} + +####################### +# Extended Definitions +####################### + +""" +The Int64 scalar type represents a signed 64‐bit numeric non‐fractional value. +Int64 can represent values in range [-(2^63),(2^63 - 1)]. +""" +scalar Int64 + +""" +The DateTime scalar type represents date and time as a string in RFC3339 format. +For example: "1985-04-12T23:20:50.52Z" represents 20 minutes and 50.52 seconds after the 23rd hour of April 12th, 1985 in UTC. +""" +scalar DateTime + +enum DgraphIndex { + int + int64 + float + bool + hash + exact + term + fulltext + trigram + regexp + year + month + day + hour +} + +input AuthRule { + and: [AuthRule] + or: [AuthRule] + not: AuthRule + rule: String +} + +enum HTTPMethod { + GET + POST + PUT + PATCH + DELETE +} + +enum Mode { + BATCH + SINGLE +} + +input CustomHTTP { + url: String! + method: HTTPMethod! + body: String + graphql: String + mode: Mode + forwardHeaders: [String!] + secretHeaders: [String!] + introspectionHeaders: [String!] + skipIntrospection: Boolean +} + +directive @hasInverse(field: String!) on FIELD_DEFINITION +directive @search(by: [DgraphIndex!]) on FIELD_DEFINITION +directive @dgraph(type: String, pred: String) on OBJECT | INTERFACE | FIELD_DEFINITION +directive @id on FIELD_DEFINITION +directive @withSubscription on OBJECT | INTERFACE +directive @secret(field: String!, pred: String) on OBJECT | INTERFACE +directive @auth( + query: AuthRule, + add: AuthRule, + update: AuthRule, + delete:AuthRule) on OBJECT +directive @custom(http: CustomHTTP, dql: String) on FIELD_DEFINITION +directive @remote on OBJECT | INTERFACE +directive @cascade(fields: [String]) on FIELD + +input IntFilter { + eq: Int + le: Int + lt: Int + ge: Int + gt: Int +} + +input Int64Filter { + eq: Int64 + le: Int64 + lt: Int64 + ge: Int64 + gt: Int64 +} + +input FloatFilter { + eq: Float + le: Float + lt: Float + ge: Float + gt: Float +} + +input DateTimeFilter { + eq: DateTime + le: DateTime + lt: DateTime + ge: DateTime + gt: DateTime +} + +input StringTermFilter { + allofterms: String + anyofterms: String +} + +input StringRegExpFilter { + regexp: String +} + +input StringFullTextFilter { + alloftext: String + anyoftext: String +} + +input StringExactFilter { + eq: String + le: String + lt: String + ge: String + gt: String +} + +input StringHashFilter { + eq: String +} + +####################### +# Generated Types +####################### + +type AddDataPayload { + data(filter: DataFilter, first: Int, offset: Int): [Data] + numUids: Int +} + +type DeleteDataPayload { + data(filter: DataFilter, first: Int, offset: Int): [Data] + msg: String + numUids: Int +} + +type UpdateDataPayload { + data(filter: DataFilter, first: Int, offset: Int): [Data] + numUids: Int +} + +####################### +# Generated Enums +####################### + +enum DataHasFilter { + intList + stringList + metaData +} + +####################### +# Generated Inputs +####################### + +input AddDataInput { + intList: [Int] + stringList: [String] + metaData: DataRef +} + +input DataFilter { + id: [ID!] + has: DataHasFilter + and: DataFilter + or: DataFilter + not: DataFilter +} + +input DataPatch { + intList: [Int] + stringList: [String] + metaData: DataRef +} + +input DataRef { + id: ID + intList: [Int] + stringList: [String] + metaData: DataRef +} + +input UpdateDataInput { + filter: DataFilter! + set: DataPatch + remove: DataPatch +} + +####################### +# Generated Query +####################### + +type Query { + getData(id: ID!): Data + queryData(filter: DataFilter, first: Int, offset: Int): [Data] +} + +####################### +# Generated Mutations +####################### + +type Mutation { + addData(input: [AddDataInput!]!): AddDataPayload + updateData(input: UpdateDataInput!): UpdateDataPayload + deleteData(filter: DataFilter!): DeleteDataPayload +} +