        ~@body)))
 
 (defmacro with-query-bindings
-  "Takes a query, a query result and an arbitrary code block.
+  "Takes a `query`, a query `result` and an arbitrary code `body`.
    Wraps the code block so that all possible bindings derived
    from the query are bound to the values in the query result."
   [query result & body]

   value of the corresponding property from a query result
   and bind it to the name of the property.

   E.g. for a property path (a b/c d) (simplified notation with
   only the property names), it would return {{{a :a} :b/c} :d},
   allowing to destructure a map like {:d {:b/c {:a <val>}}}
   and bind a to <val>.

   It treats backref properties like _b/c in joins special by
   binding to b instead of c (the regular case) or _b."
  [[leaf & path]]
  (loop [form {(or (some-> leaf :alias simplified-name symbol)
                   (if (util/backref-attr? (:name leaf))

  :ret ::core-specs/map-bindings)

(defn query-bindings
  "Takes a `query` or parsed query and returns map bindings to
   be applied to the corresponding query result in order to
   destructure and bind all possible properties in the query
   result to their names.

   E.g. for a query `[a :as b c [d e {f [g :as h]}]]` it
   would return `{b :a, d :c/d, e :c/e, f :f, {{h :g} :f}}`."
  [query]
  (let [paths    (binding-paths query)
        bindings (mapv path-bindings paths)
