   ;; executed. Current implementation will merge result from multiple
   ;; statements.
   (let [results (map #(execute-statement % state) document)
-        [errors fields] (rollup-errors results)]
+        {:keys [errors vals]} (rollup-errors results)]
     (if (seq errors)
       {:errors errors}
-      {:data (into {} fields)})))
+      {:data (into {} vals)})))
 
 ;; Public API
 

                  (into {}))]
    (merge default-args args)))

(defn- resolve-field-on-object
  [{:keys [resolver-fn name arguments] :as field-entry} field-def {:keys [context resolver variables] :as state} parent-type-name parent-result]
  (assert field-entry (format "field-entry is nil! parent-type-name: %s." parent-type-name))
  (assert field-def (format "field-def is nil!"))
  (let [resolve (or resolver-fn
                    (resolver (str parent-type-name) (str name)))
        default-arguments (:arguments field-def)]
    (assert resolve (format "Resolver is nil: parent-type-name:%s, name:%s." parent-type-name name))
    [nil (resolve context parent-result (args arguments default-arguments variables))]))

(declare execute-fields)

(defn- rollup-errors
  "For list of [errors result], accumunate errors and flatten to one list as new-errors, and accomunate result and flatten to another list as new-results, return [new-erros new-results]"
  [results]
  (let [errors (->> results
                    (filter first)
                    (map first)
                    flatten
                    vec)
        vals (->> results
                  (filter second)
                  (map second)
                  vec)]
    [errors vals]))


(defn- complete-value
  "return pair of errors and result"
  [{:keys [selection-set name type resolved-type] :as field-entry} {:keys [schema] :as state} [errors result]]
  (when (and (:required resolved-type) (nil? result))
    (throw (ex-info (format "NOT_NULL field \"%s\" assigned a null value." name)
                    {:errors [{:message (format "NOT_NULL field \"%s\" assigned a null value." name)}]})))
  (assert type (format "type if nil for field(%s)." name))
  (let [type-name (:name type)
        tag (:tag type)
        inner-type (:inner-type type)]
    (when result
      (cond
        (#{:scalar-definition :union-definition :enum-definition} tag) [errors result]
        (#{:type-definition} tag) (execute-fields selection-set state type-name [errors result])
        (#{:interface-definition} tag) (execute-fields selection-set state type-name [errors result])
        (#{:basic-type} tag) (let [unwrapped-type (get-in schema [:type-map type-name])]
                               (complete-value (assoc field-entry :type unwrapped-type) state [errors result]))
        (#{:list-type} tag) (do
                              (let [list-result (map #(complete-value {:selection-set selection-set
                                                                       :type inner-type
                                                                       :require (:required type)} state %) [errors result])]
                                (prn "list-result:" list-result)
                                (rollup-errors list-result)))
        :else (gerror/throw-error (format "Unhandled field(%s) type: %s%n field-entry:%s%n" name type field-entry))))))

(defn- get-field-entry [{:keys [alias name field-name] :as selection} field-def state parent-type-name parent-result]
  (assert selection "selection is nil!")
  (assert field-def (format "field-def is nil for selection: %s." selection))
  (let [[errors result :as completed-value] (->> (resolve-field-on-object selection field-def state parent-type-name parent-result)
                                                 (complete-value selection state))]
    (prn "complete-value:" completed-value)
    [errors [(str (or alias name field-name)) result]]))

(defn- get-field-type
  [schema parent-type-name field-name]

(defn- execute-field
  "return vector of [errors field]"
  [selection field-map state parent-type-name parent-value]
  (assert (validate-result-format parent-value) "parent-value is not valid.")
  (let [selection-name (:name selection)
        field-def (get field-map selection-name)
        _ (assert selection-name (format "No name for selection: %s." selection))
