lacinia icon indicating copy to clipboard operation
lacinia copied to clipboard

Undeclared variable in fragment not used by operation

Open xiongtx opened this issue 5 years ago • 2 comments

When multiple queries are declared in a query document but the chosen operation doesn't reference a schema that requires a variable, there is a parse error.

Given the following schema, which we'll call schema:

{:objects
 {:Business {:fields {:name {:type String}
                      :owners {:type (list :Owner)}}}
  :Owner {:fields {:name {:type String}
                   :owned_businesses {:type (list :Business)
                                      :args {:location {:type String}}
                                      :resolve :placeholder}}}}

 :queries
 {:owners {:type (list :Owner)
           :resolve :placeholder}
  :businesses {:type (list :Business)
               :args {:location {:type String}}
               :resolve :placeholder}}}

And query document, which we'll call query-doc:

query BusinessesQuery($location: String) {
 businesses(location: $location) {
  owners {
   ...OwnerFields
  }
 }
}

fragment OwnerFields on Owner {
 name
 owned_businesses(location: $location)
}

query OwnerNamesQuery {
 owners {
  name
 }
}

This parses fine:

(require '[com.walmartlabs.lacinia.parser :as lacinia-parser])

(lacinia-parser/parse-query schema query-doc "BusinessesQuery")

But this throws an exception:

(lacinia-parser/parse-query schema query-doc "OwnerNamesQuery")
Argument references undeclared variable `location'.
   {:locations [{:line 10, :column 2}],
    :field :Owner/owned_businesses,
    :argument :Owner/owned_businesses.location,
    :unknown-variable :location,
    :declared-variables ()}

The problem appears to be that fragments are included without considering whether the chosen operation makes use of them.

xiongtx avatar May 20 '20 17:05 xiongtx

I'm noodling on a way to do the checks for this that aren't too expensive in terms of navigating around the selection set. I'd probably want to catch recursive fragments at the same time.

hlship avatar Sep 25 '20 22:09 hlship

This looks like a bug, but I'm struggling to figure out a way to properly recognize defined-by-not-referenced fragments, as well as exclude fragments such as in this case. I probably need to look into spec to see what is required w.r.t validation of fragments in cases such as this.

hlship avatar Dec 16 '21 01:12 hlship