Fixes #298 by restoring multi-CTE capability
Reverts code changes that stripped the sequence support. Updates the docs to clarify how sequence support works.
This commit is contained in:
parent
e02b5b5c82
commit
0a83601c3c
4 changed files with 54 additions and 3 deletions
|
|
@ -12,7 +12,53 @@ Except as noted, these clauses apply to all the SQL
|
|||
dialects that HoneySQL supports.
|
||||
|
||||
## nest
|
||||
|
||||
This is pseudo-syntax that lets you wrap a substatement
|
||||
in an extra level of parentheses. It should rarely be
|
||||
needed and it is mostly present to provide the same
|
||||
functionality for clauses that `[:nest ..]` provides
|
||||
for expressions.
|
||||
|
||||
## with, with-recursive
|
||||
|
||||
These provide CTE support for SQL Server. The argument to
|
||||
`:with` (or `:with-recursive`) is a sequences of pairs, each of
|
||||
a result set name (or description) and a basic SQL statement.
|
||||
The result set can either be a SQL entity (a simple name)
|
||||
or a pair of a SQL entity and a set of column names.
|
||||
|
||||
```clojure
|
||||
user=> (sql/format '{with ((stuff {select (:*) from (foo)}),
|
||||
(nonsense {select (:*) from (bar)}))
|
||||
select (foo.id,bar.name)
|
||||
from (stuff, nonsense)
|
||||
where (= status 0)})
|
||||
["WITH stuff AS (SELECT * FROM foo), nonsense AS (SELECT * FROM bar) SELECT foo.id, bar.name FROM stuff, nonsense WHERE status = ?" 0]
|
||||
```
|
||||
|
||||
You can specify a list of columns for the CTE like this:
|
||||
|
||||
```clojure
|
||||
user=> (sql/format {:with [[[:stuff {:columns [:id :name]}]
|
||||
{:select [:*] :from [:foo]}]]
|
||||
:select [:id :name]
|
||||
:from [:stuff]
|
||||
:where [:= :status 0]})
|
||||
["WITH stuff (id, name) AS (SELECT * FROM foo) SELECT id, name FROM stuff WHERE status = ?" 0]
|
||||
```
|
||||
|
||||
You can use a `VALUES` clause in the CTE:
|
||||
|
||||
```clojure
|
||||
user=> (sql/format {:with [[[:stuff {:columns [:id :name]}]
|
||||
{:values [[1 "Sean"] [2 "Jay"]]}]]
|
||||
:select [:id :name]
|
||||
:from [:stuff]})
|
||||
["WITH stuff (id, name) AS (VALUES (?, ?), (?, ?)) SELECT id, name FROM stuff" 1 "Sean" 2 "Jay"]
|
||||
```
|
||||
|
||||
`:with-recursive` follows the same rules as `:with` and produces `WITH RECURSIVE` instead of just `WITH`.
|
||||
|
||||
## intersect, union, union-all, except, except-all
|
||||
|
||||
These all expect a sequence of SQL clauses, those clauses
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ values identified in the SQL expressions:
|
|||
;;=> ["SELECT * FROM table WHERE id = ?" 1]
|
||||
```
|
||||
|
||||
Any values found in the data structure, that are not keywords
|
||||
By default, any values found in the data structure, that are not keywords
|
||||
or symbols, are treated as positional parameters and replaced
|
||||
by `?` in the SQL string and lifted out into the vector that
|
||||
is returned from `format`.
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@
|
|||
(assoc {} k data)))
|
||||
|
||||
(defn nest [& args] (generic :nest args))
|
||||
(defn with [& args] (generic-1 :with args))
|
||||
(defn with-recursive [& args] (generic-1 :with-recursive args))
|
||||
(defn with [& args] (generic :with args))
|
||||
(defn with-recursive [& args] (generic :with-recursive args))
|
||||
;; these five need to supply an empty hash map since they wrap
|
||||
;; all of their arguments:
|
||||
(defn intersect [& args] (generic :intersect (cons {} args)))
|
||||
|
|
|
|||
|
|
@ -99,6 +99,11 @@
|
|||
(deftest test-cte
|
||||
(is (= (format {:with [[:query {:select [:foo] :from [:bar]}]]})
|
||||
["WITH query AS (SELECT foo FROM bar)"]))
|
||||
(is (= (format {:with [[:query1 {:select [:foo] :from [:bar]}]
|
||||
[:query2 {:select [:bar] :from [:quux]}]]
|
||||
:select [:query1.id :query2.name]
|
||||
:from [:query1 :query2]})
|
||||
["WITH query1 AS (SELECT foo FROM bar), query2 AS (SELECT bar FROM quux) SELECT query1.id, query2.name FROM query1, query2"]))
|
||||
(is (= (format {:with-recursive [[:query {:select [:foo] :from [:bar]}]]})
|
||||
["WITH RECURSIVE query AS (SELECT foo FROM bar)"]))
|
||||
(is (= (format {:with [[[:static {:columns [:a :b :c]}] {:values [[1 2 3] [4 5]]}]]})
|
||||
|
|
|
|||
Loading…
Reference in a new issue