korma / Korma

Tasty SQL for Clojure.
http://sqlkorma.com
1.48k stars 222 forks source link

Exception in parse-aggregate #339

Open rahulmutt opened 8 years ago

rahulmutt commented 8 years ago

In engine/parse-aggregate, it checks if it returns a string and if it is, will return the string itself. The only place in the entire project that parse-aggregate is used is in core/aggregate where the result of that function evaluated will be threaded-first with the query. Now suppose you actually pass in a string for the "agg" argument like so:

(defentity a)
(-> (select* a) (aggregate "a" :a) (as-sql))

This will cause the following error:

Unhandled java.lang.ClassCastException
java.lang.String cannot be cast to clojure.lang.IFn

I have no idea what the intended behavior was, but it makes sense that if a string is passed in, it should be taken as a override (which is needed in my case and which is how I stumbled upon this). I suggest the following changes:

engine.clj

(defn parse-aggregate [form]
  (if (string? form)
    `(korma.sql.fns/agg-all ~form)
    (walk/postwalk-replace aggregates form)))

fns.clj

(defn agg-all [_query_ v] v)
rahulmutt commented 8 years ago

Here's a shorter version without modifying fns.clj:

engine.clj

(defn parse-aggregate [form]
  (if (string? form)
    `((constantly ~form))
    (walk/postwalk-replace aggregates form)))
immoh commented 8 years ago

Actually I think better way to fix this would be to remove _query_ parameter from aggregate functions (none of them is using it anymore) and stop passing it when calling the returned function in aggregate. Please submit a pull request with a test case.