 ;; `:bindings` is a map from var to qualified columns.
 ;; `:wheres` is a list of fragments that can be joined by `:and`.
 ;;
-(defrecord Context [from bindings wheres attribute-transform constant-transform])
+(defrecord Context [from bindings wheres elements attribute-transform constant-transform])
 
 (defn attribute-in-context [context attribute]
   ((:attribute-transform context) attribute))


     [[:datoms12.e :foo] [:datoms13.e :bar]]

   @param context A Context.
   @param elements The input clause.
   @return a sequence of pairs."
  [context elements]
  (when-not (every? #(instance? Variable %1) elements)
    (raise "Unable to :find non-variables."))
  (map (fn [elem]
         (let [var (:symbol elem)]
           [(lookup-variable context var) (var->sql-var var)]))
       elements))

(defn context->sql-clause [context elements]
  {:select (elements->sql-projection context elements)
   :from (:from context)
   :where (if (empty? (:wheres context))
            nil

  (when-not (and (== 1 (count in))
                 (= "$" (name (-> in first :variable :symbol))))
    (raise (str "Complex `in` not supported: " (print-str in)))))

(defn find->prepared-context [find]
  ;; There's some confusing use of 'where' and friends here. That's because
  ;; the parsed Datalog includes :where, and it's also input to honeysql's
  ;; SQL formatter.
  (let [{:keys [find in with where]} find]  ; Destructure the Datalog query.
    (validate-with with)
    (validate-in in)
    (apply-elements-to-context
      (expand-where-from-bindings
        (patterns->context where))    ; 'where' here is the Datalog :where clause.
      (:elements find))))

(defn find->sql-clause
  "Take a parsed `find` expression and turn it into a structured SQL
