honeysql

Discussion of https://github.com/seancorfield/honeysql :slightly_smiling_face:
2020-07-03T09:39:29.171Z

Hi, i am having a weird problem using (sql/call) or probably i am missing something i have this query:

(-> (h/select (hql/call :coalesce :settlement-days 1))
    (h/from :trd_fund))
if i format the query on the same namespace it works just fine, this is the output: [SELECT coalesce("settlement_days", ?) FROM "trd_fund" 1] but if i pass this query to be formatted another ns then the query doesnt’ generate the sql for the function: [SELECT ( ) FROM "trd_fund"]

2020-07-03T09:46:59.171400Z

same thing happens if i use sql/raw . also tried with a simlpe function like :%now and same thing. in all cases the function is not present when formatted on a different ns

seancorfield 2020-07-03T16:37:55.172700Z

@jmayaalv Sounds like your other namespace isn't causing honeysql.types to be required. I would have expected that to required by honeysql.core...

seancorfield 2020-07-03T16:39:46.173800Z

...which it definitely does. Odd. Can you put together a simple repro of this on GitHub somewhere that I can take a look? And then create an issue on the HoneySQL repo linking to your repro on GitHub. Thanks.

seancorfield 2020-07-03T16:39:56.174100Z

I have never seen that behavior.

2020-07-03T17:07:19.174700Z

Thank you @seancorfield, will do

2020-07-03T17:55:27.176300Z

oddly enough i can’t reproduce it on a clean project πŸ˜•

seancorfield 2020-07-03T17:57:00.178200Z

Well... it is certainly unexpected behavior so I would imagine it's something fairly unusual about your current project (or maybe just bad REPL state?).

2020-07-03T17:58:09.179Z

for sure not the repl. will dig deeper on the dependencies, hopefully will find something and let you know πŸ™‚ thanks for the help

2020-07-03T19:47:28.180500Z

@seancorfield managed to reproduce it, what happened is that we were passing the query to a map, then the map was walked with a postwalk to remove nils

2020-07-03T19:47:41.180900Z

(defn remove-nils
  [m]
  (let [f (fn [[k v]] (when (not (nil? v)) [k v]))]
    (walk/postwalk (wfn [x]
                (if (map? x)
                  (into {} (map f x))
                  x))
              m)))

2020-07-08T15:46:45.188600Z

(not (nil? v)) can be (some? v)

2020-07-08T15:48:16.188800Z

(into {} (map f x)) should be (into {} (keep f x))

2020-07-08T15:48:52.189Z

@jmayaalv otherwise your map will contain the association [nil nil]

πŸ‘ 1
2020-07-08T15:54:46.189500Z

thanks, at the end we dont need to do a postwalk, so code is now much simpler, but thank you for the suggestion

2020-07-08T15:58:28.189800Z

in fact, it could also be just (into {} (filter (comp some? second)) x)

2020-07-08T15:59:21.190Z

or (into {} (remove (comp nil? second)) x)

2020-07-03T19:50:22.182400Z

before the postwalk: {:select (#sql/call [:coalesce :f.bla 1]), :from ([:foo :f])} after the postwalk: {:select ({:name :coalesce, :args (:f.bla 1)}), :from ([:foo :f])}

2020-07-03T19:51:14.183400Z

πŸ˜…

seancorfield 2020-07-03T19:51:50.183700Z

Ouch! Yup, that would break the structure.

seancorfield 2020-07-03T19:52:42.184600Z

So the problem is that records satisfy map? but then you are turning them into plain ol' hash maps and losing the record type.

seancorfield 2020-07-03T19:54:48.185500Z

You could check for (and (map? x) (not (instance? clojure.lang.IRecord x))) instead of just (map? x) and it should work @jmayaalv

2020-07-03T19:55:32.186Z

yeah, thanks a lot πŸ™‚ you are awesome!