neo4j-graphql / neo4j-graphql-js

NOTE: This project is no longer actively maintained. Please consider using the official Neo4j GraphQL Library (linked in README).
Other
608 stars 148 forks source link

Syntax error in the generated query after upgrading to 2.16.4 #527

Open iledzka opened 3 years ago

iledzka commented 3 years ago

Hello,

I recently updated from the version 2.7.2 to 2.16.4 and this caused a lot of my queries to fail with error like this

"Invalid input ']': expected whitespace, comment or an expression

This is the debug output:

{"errors":[{"message":"Invalid input ']': expected whitespace, comment or an expression (line 1, column 3667 (offset: 3666))\n\"WITH apoc.cypher.runFirstColumn(\"MATCH(:Person {id: $personId})-[:HAS|HAS_MEMBER]-(project:Project {id: $projectId}) RETURN project\", {offset:$offset, first:$first, personId:$personId, projectId:$projectId}, True) AS x UNWIND x AS `project` RETURN `project` { .id , .title , .status , .type ,creationDate: { formatted: toString(`project`.creationDate) },lastModifiedDate: { formatted: toString(`project`.lastModifiedDate) },pendingInvitations: [ project_pendingInvitations IN apoc.cypher.runFirstColumn(\"MATCH (this)-[:HAS_INVITATION]->(i:Invitation { isArchived: false, status: \\\"PENDING\\\" }) WHERE datetime(i.reminderDate) < datetime() RETURN i \", {this: project}, true) | project_pendingInvitations { .id , .status ,reminderDate: { formatted: toString(`project_pendingInvitations`.reminderDate) },creator: head([(`project_pendingInvitations`)-[:`HAS_CREATOR`]->(`project_pendingInvitations_creator`:`Person`) | `project_pendingInvitations_creator` { .id }]) ,invitee: [ project_pendingInvitations_invitee IN apoc.cypher.runFirstColumn(\" MATCH (this)-[:HAS_INVITEE]->(person:Person) WHERE NOT exists(person.isArchived) OR NOT person.isArchived=true RETURN person \", {this: project_pendingInvitations}, true) | project_pendingInvitations_invitee { .id , .fullName }] }] ,invitations: [(`project`)-[:`HAS_INVITATION`]->(`project_invitations`:`Invitation`) | `project_invitations` { .id }] ,members: [(`project`)-[:`HAS_MEMBER`]->(`project_members`:`Person`) | `project_members` { .id , .accountId , .fullName , .keyName , .abbreviatedName , .description , .emailAddress , .authStatus ,creationDate: { formatted: toString(`project_members`.creationDate) },imageDepictions: [(`project_members`)<-[:`DEPICTS`]-(`project_members_imageDepictions`:`Image`) | `project_members_imageDepictions` { .id , .title , .type ,thumbnail: [ project_members_imageDepictions_thumbnail IN apoc.cypher.runFirstColumn(\" MATCH (this)-[:HAS_THUMBNAIL]->(thumb) WHERE thumb.isArchived=false RETURN thumb \", {this: project_members_imageDepictions}, true) | project_members_imageDepictions_thumbnail { .id ,file: [(`project_members_imageDepictions_thumbnail`)-[:`IN_FILE`]->(`project_members_imageDepictions_thumbnail_file`:`File`) | `project_members_imageDepictions_thumbnail_file` { .uri }] }] }] ,invitationsReceived: [(`project_members`)<-[:`HAS_INVITEE`]-(`project_members_invitationsReceived`:`Invitation`) | `project_members_invitationsReceived` { .id ,creator: head([(`project_members_invitationsReceived`)-[:`HAS_CREATOR`]->(`project_members_invitationsReceived_creator`:`Person`) | `project_members_invitationsReceived_creator` { .id }]) }] }] ,owners: [(`project`)<-[:`HAS`]-(`project_owners`:`Party`) WHERE (\"Person\" IN labels(`project_owners`)) | head([`project_owners` IN [`project_owners`] WHERE \"Person\" IN labels(`project_owners`) | `project_owners` { FRAGMENT_TYPE: \"Person\",  .id , .accountId , .fullName , .keyName , .abbreviatedName , .description , .emailAddress , .authStatus ,imageDepictions: [(`project_owners`)<-[:`DEPICTS`]-(`project_owners_imageDepictions`:`Image`) | `project_owners_imageDepictions` { .id , .title , .type ,thumbnail: [ project_owners_imageDepictions_thumbnail IN apoc.cypher.runFirstColumn(\" MATCH (this)-[:HAS_THUMBNAIL]->(thumb) WHERE thumb.isArchived=false RETURN thumb \", {this: project_owners_imageDepictions}, true) | project_owners_imageDepictions_thumbnail { .id ,file: [(`project_owners_imageDepictions_thumbnail`)-[:`IN_FILE`]->(`project_owners_imageDepictions_thumbnail_file`:`File`) | `project_owners_imageDepictions_thumbnail_file` { .uri }] }] }]  }])] ,resources: [(`project`)-[:`HAS_RESOURCE`]->(`project_resources`:`Resource`) | ] ,comments: [ project_comments IN apoc.cypher.runFirstColumn(\" MATCH (this)<-[:COMMENT_ON]-(com) WHERE com.isArchived=false RETURN com ORDER BY com.lastModifiedDate desc \", {this: project}, true) | project_comments { .id , .text ,creationDate: { formatted: toString(`project_comments`.creationDate) },author: head([(`project_comments`)<-[:`COMMENTED`]-(`project_comments_author`:`Person`) | `project_comments_author` { .id , .accountId , .fullName }]) }] ,genres: [(`project`)<-[:`IN_GENRE`]-(`project_genres`:`Genre`) | `project_genres` { .id , .name }] } AS `project`\"\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   ^","locations":[{"line":2,"column":3}],"path":["Project"],"extensions":{"code":"INTERNAL_SERVER_ERROR","exception":{"code":"Neo.ClientError.Statement.SyntaxError","name":"Neo4jError"}}}],"data":{"Project":null}}

When I run this query in the neo4j browser, I get this:

Invalid input '\': expected whitespace, DISTINCT, an expression or ')' (line 1, column 33 (offset: 32))

Any help is appreciated.

michaeldgraham commented 3 years ago

Hey there! Could you share a minimal example of your schema and a query that reproduces this error? Thank you 💯

hungry-thom commented 3 years ago

I have run into a similar issue while trying to work with interface types. I am new to all of this, so please excuse my ignorance. In my situation, was trying to create a relationship between two interfaces, as part of an interface. To demonstrate, i will try to build off the example provided on the interface and union type page in the documentation:

`interface Person { personid: ID! name: String likes: [Likes] }

type Likes @relation(name: "LIKES") { from: Person to: Subject rating: Float }

interface Subject { subjectid: ID! name: String }

type Maths implements Subject { subjectid: ID! name: String level: String }

type User implements Person { personid: ID! name: String likes: [Likes] screenName: String }`

Adding the data: mutation { u1: CreateUser(name: "Bob", screenName: "bobbyTables", personid: "u1") { personid } s1: CreateMaths(name: "Calculus", subjectid: "s1", level: "Undergrad") { name subjectid level } l1: AddUserLikes(from: { personid: "u1" }, to: { subjectid: "s1" }, data:{ rating: 3.3}) { from { personid } to { subjectid } rating } }

AddUserLikes does seem to establish the realationship, but results in this error for both Person and Subject: "Abstract type \"Person\" must resolve to an Object type at runtime for field \"_AddUserLikesPayload.from\". Either the \"Person\" type should provide a \"resolveType\" function or each possible type should provide an \"isTypeOf\" function."

I don't remember receiving that error when making simiar additions in the past. I am not sure if am using proper technique. but when I try to query using the interfaces:

query { Person { likes { Subject { ... on Maths { name } } } } }

I recognize this query may be incorrect, but it is how I get an error similar to op (also if quering User): "Invalid input ']': expected whitespace, comment or an expression (line 1, column 364 (offset: 363))\n\"MATCH (person:Person) RETURNperson{FRAGMENT_TYPE: head( [ label IN labels(person) WHERE label IN $Person_derivedTypes ] ),likes: [(person)-[person_likes_relation:LIKES]->(:Subject) | person_likes_relation {Subject: head([(:Person)-[person_likes_relation]->(person_likes_Subject:Subject) WHERE (\"Maths\" IN labels(person_likes_Subject)) | ]) }] } ASperson\"\n

It definitely seems tied to the interface in my case. When I try the simple query:

query { Person { name } }

I get the previous abstract type error (even when following the documentation example exactly) : Abstract type \"Person\" must resolve to an Object type at runtime for field \"Query.Person\". Either the \"Person\" type should provide a \"resolveType\" function or each possible type should provide an \"isTypeOf\" function.

Again, I am new to all this, so I understand I may be going about this all wrong. The fact that I can't even query Person has me worried, though. Any insight is greatly appreciated. Thanks!

dantestopp commented 3 years ago

Any updates regarding this issue?

iledzka commented 3 years ago

Hey there! Could you share a minimal example of your schema and a query that reproduces this error? Thank you 💯

Apologies for late response. I reverted to 2.7.2 because this is for an app that it's in production ;) I created a new branch and tried to reproduce this and I can confirm that the bug is definitely related to Interfaces.

Schema:

interface Component {
    id: ID!
    title: String
...
  }

interface Resource {
    id: ID!
    resourceOf: [Project] @relation(name: "HAS_RESOURCE", direction: "IN")
  }

type Image implements Component & Resource (...& other interfaces...) {
    id: ID!
    title: String
    subtitle: String
    version: String
    creationDate: _Neo4jDateTime
   ...
  }

type Project implements Component & Resource {
id: ID!
resources: [Resource] @relation(name: "HAS_RESOURCE", direction: "OUT")
}

An example of a query:

query getProject(
$personId:ID!,
    $projectId: ID!
  ) {
  Project(
    projectId: $projectId,
personId: $personId
  ) {
    id,
    resources {
      ...on Component {
        id,
        title
      }
      __typename
    }
  }
}

if I remove the fragment ...on Component, I don't get the error. If I change this fragment to be "...on Resources", I get different error:

"invalid literal number (line 1, column 568 (offset: 567))\n\"WITH apoc.cypher.runFirstColumn(\"MATCH(:Person {id: $personId})-[:HAS|HAS_MEMBER]-(project:Project {id: $projectId}) RETURN project\", {offset:$offset, first:$first, personId:$personId, projectId:$projectId}, True) AS x UNWIND x AS `project` RETURN `project` { .id ,resources: [(`project`)-[:`HAS_RESOURCE`]->(`project_resources`:`Resource`) WHERE (\"Image\" IN labels(`project_resources`) OR \"Recording\" IN labels(`project_resources`) OR \"SourceFile\" IN labels(`project_resources`) OR \"Text\" IN labels(`project_resources`) OR \"Video\" IN labels(`project_resources`)) |  .id ] } AS `project`\"\n

Thanks for your help!

gabriellovric commented 3 years ago

This issue should be resolved with the PR, I would be happy to hear if it worked for you too.

hungry-thom commented 3 years ago

Whooo! That seems to work for me!! Thanks!

michaeldgraham commented 3 years ago

https://github.com/neo4j-graphql/neo4j-graphql-js/issues/608