add distinct/expr clauses
This commit is contained in:
parent
75830df509
commit
ac09fc1abd
5 changed files with 42 additions and 11 deletions
|
|
@ -1,7 +1,7 @@
|
|||
# Changes
|
||||
|
||||
* 2.4.next in progress
|
||||
* Address [#504](https://github.com/seancorfield/honeysql/issues/504) by adding special syntax for ignore/respect nulls. More work will be needed to support distinct/order by/limit in BigQuery array aggregation.
|
||||
* Address [#504](https://github.com/seancorfield/honeysql/issues/504) for BigQuery support, by adding special syntax for ignore/respect nulls, as well as new `:distinct` and `:expr` clauses to allow expressions to be qualified with SQL clauses. The latter will probably be useful for other dialects too.
|
||||
|
||||
* 2.4.1066 -- 2023-08-27
|
||||
* Add `:select` with function call and alias example to README (PR [#502](https://github.com/seancorfield/honeysql/pull/502) [@markbastian](https://github.com/markbastian)).
|
||||
|
|
|
|||
|
|
@ -52,11 +52,11 @@ section of the documentation before trying to use HoneySQL to build your own que
|
|||
From Clojure:
|
||||
<!-- {:test-doc-blocks/reader-cond :clj} -->
|
||||
```clojure
|
||||
(refer-clojure :exclude '[filter for group-by into partition-by set update])
|
||||
(refer-clojure :exclude '[distinct filter for group-by into partition-by set update])
|
||||
(require '[honey.sql :as sql]
|
||||
;; CAUTION: this overwrites several clojure.core fns:
|
||||
;;
|
||||
;; filter, for, group-by, into, partition-by, set, and update
|
||||
;; distinct, filter, for, group-by, into, partition-by, set, and update
|
||||
;;
|
||||
;; you should generally only refer in the specific
|
||||
;; helpers that you want to use!
|
||||
|
|
|
|||
|
|
@ -1002,6 +1002,19 @@ user=> (sql/format (-> (select :id
|
|||
["SELECT id, AVG(salary) OVER () AS Average, MAX(salary) OVER () AS MaxSalary FROM employee"]
|
||||
```
|
||||
|
||||
## distinct, expr
|
||||
|
||||
Related to the windowing clauses above, `:distinct` and `:expr` are
|
||||
intended to let you mix clauses with expressions, such as in BigQuery's
|
||||
`ARRAY_AGG` function:
|
||||
|
||||
```clojure
|
||||
user=> (sql/format {:select [[[:over
|
||||
[[:array_agg {:distinct [:ignore-nulls :col] :order-by :x}]
|
||||
{:partition-by :y}]]]]})
|
||||
["SELECT ARRAY_AGG (DISTINCT col IGNORE NULLS ORDER BY x ASC) OVER (PARTITION BY y)"]
|
||||
```
|
||||
|
||||
## order-by
|
||||
|
||||
`:order-by` accepts a sequence of one or more ordering
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
:raw :nest :with :with-recursive :intersect :union :union-all :except :except-all
|
||||
:table
|
||||
:select :select-distinct :select-distinct-on :select-top :select-distinct-top
|
||||
:distinct :expr
|
||||
:into :bulk-collect-into
|
||||
:insert-into :replace-into :update :delete :delete-from :truncate
|
||||
:columns :set :from :using
|
||||
|
|
@ -288,13 +289,14 @@
|
|||
|
||||
Any ? is escaped to ??."
|
||||
[k]
|
||||
(when k
|
||||
(let [n (str/replace (name k) "?" "??")]
|
||||
(if (= \' (first n))
|
||||
(let [ident (subs n 1 (count n))
|
||||
ident-l (str/lower-case ident)]
|
||||
(binding [*quoted* (when-not (contains? #{"array"} ident-l) *quoted*)]
|
||||
(format-entity (keyword ident))))
|
||||
(-> n (dehyphen) (upper-case)))))
|
||||
(-> n (dehyphen) (upper-case))))))
|
||||
|
||||
(defn- sym->kw
|
||||
"Given a symbol, produce a keyword, retaining the namespace
|
||||
|
|
@ -1361,6 +1363,8 @@
|
|||
:select-distinct-on #'format-selects-on
|
||||
:select-top #'format-select-top
|
||||
:select-distinct-top #'format-select-top
|
||||
:distinct (fn [k xs] (format-selects k [[xs]]))
|
||||
:expr (fn [_ xs] (format-selects nil [[xs]]))
|
||||
:into #'format-select-into
|
||||
:bulk-collect-into #'format-select-into
|
||||
:insert-into #'format-insert
|
||||
|
|
@ -2269,4 +2273,8 @@
|
|||
[:transport :t] [:id :name]]
|
||||
:values [[1 "Car"] [2 "Boat"] [3 "Bike"]]}
|
||||
{:pretty true})
|
||||
(sql/format-expr [:array_agg {:distinct [:ignore-nulls :a] :order-by :a}])
|
||||
(sql/format-expr [:over [[:array_agg {:expr [:respect-nulls :a] :order-by :a
|
||||
:limit 10}]
|
||||
{:partition-by :something}]])
|
||||
)
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
bulk-collect-info [& args]
|
||||
|
||||
(as they are for all helper functions)."
|
||||
(:refer-clojure :exclude [filter for group-by into partition-by set update])
|
||||
(:refer-clojure :exclude [distinct filter for group-by into partition-by set update])
|
||||
(:require [clojure.core :as c]
|
||||
[honey.sql]))
|
||||
|
||||
|
|
@ -468,6 +468,16 @@
|
|||
[& args]
|
||||
(generic :select-distinct-top args))
|
||||
|
||||
(defn distinct
|
||||
"Like `select-distinct` but produces DISTINCT..."
|
||||
[& args]
|
||||
(generic-1 :distinct args))
|
||||
|
||||
(defn expr
|
||||
"Like `distinct` but produces ... (i.e., just the expression that follows)."
|
||||
[& args]
|
||||
(generic-1 :expr args))
|
||||
|
||||
(defn into
|
||||
"Accepts table name, optionally followed a database name."
|
||||
{:arglists '([table] [table dbname])}
|
||||
|
|
|
|||
Loading…
Reference in a new issue