fix #497 by adding tests and documenting :alias
This commit is contained in:
parent
2f99103ed1
commit
686cbf7272
5 changed files with 84 additions and 18 deletions
|
|
@ -3,7 +3,7 @@
|
|||
* 2.4.next in progress
|
||||
* Add `:create-or-replace-view` to support PostgreSQL's lack of `IF NOT EXISTS` for `CREATE VIEW`.
|
||||
* Add `:select` with function call and alias example to README (PR [#502](https://github.com/seancorfield/honeysql/pull/502) [@markbastian](https://github.com/markbastian)).
|
||||
* Address [#497](https://github.com/seancorfield/honeysql/issues/497) by adding `:alias` special syntax. Documentation TBD.
|
||||
* Address [#497](https://github.com/seancorfield/honeysql/issues/497) by adding `:alias` special syntax.
|
||||
* Attempt to clarify the formatting behavior of the `:values` clause when used to produce column names.
|
||||
* Update `tools.build` to 0.9.5 (and remove `:java-opts` setting from `build/run-task`)
|
||||
|
||||
|
|
|
|||
|
|
@ -490,6 +490,16 @@ Here, `:select` has a three expressions as its argument. The first is
|
|||
a simple column name. The second is an expression and its alias. The
|
||||
third is a simple column name and its alias.
|
||||
|
||||
An alias can be a simple name (a keyword or a symbol) or a string. An alias
|
||||
containing a dot (`.`) is treated as a single name for quoting purposes.
|
||||
Otherwise, a simple name will be formatted using table and column name rules
|
||||
(including `-` to `_` translation). An alias specified as a string will not get
|
||||
the `-` to `_` translation. There may be other contexts where you need to
|
||||
refer to an alias but don't want the table/column rules applied to it, e.g.,
|
||||
in an `:order-by` clause. You can use the special syntax `[:alias :some.thing]`
|
||||
to tell HoneySQL to treat `:some.thing` as an alias instead of a table/column
|
||||
name reference.
|
||||
|
||||
`:select-distinct` works the same way but produces `SELECT DISTINCT`.
|
||||
|
||||
> Google BigQuery support: to provide `SELECT * EXCEPT ..` and `SELECT * REPLACE ..` syntax, HoneySQL supports a vector starting with `:*` or the symbol `*` followed by except columns and/or replace expressions as columns:
|
||||
|
|
@ -967,6 +977,11 @@ user=> (sql/format {:select [:*] :from :table
|
|||
["SELECT * FROM table ORDER BY CASE WHEN NOW() < expiry_date THEN created_date ELSE expiry_date END DESC"]
|
||||
```
|
||||
|
||||
You can `ORDER BY` column names (`:col1`), or table and column (`:table.col1`),
|
||||
or aliases (`:some.alias`). Since there is ambiguity between the formatting
|
||||
of those, you can use the special syntax `[:alias :some.thing]` to tell
|
||||
HoneySQL to treat `:some.thing` as an alias instead of a table/column name.
|
||||
|
||||
## limit, offset, fetch
|
||||
|
||||
Some databases, including MySQL, support `:limit` and `:offset`
|
||||
|
|
|
|||
|
|
@ -6,6 +6,31 @@ as special syntactic forms.
|
|||
|
||||
The first group are used for SQL expressions. The second (last group) are used primarily in column definitions (as part of `:with-columns` and `:add-column` / `:alter-column`).
|
||||
|
||||
The examples in this section assume the following:
|
||||
|
||||
```clojure
|
||||
(require '[honey.sql :as sql])
|
||||
```
|
||||
|
||||
## alias
|
||||
|
||||
Accepts a single argument which should be an alias name (from an `AS` clause
|
||||
elsewhere in the overall SQL statement) and uses alias formatting rules rather
|
||||
than table/column formatting rules (different handling of dots and hyphens).
|
||||
This allows you to override HoneySQL's default assumption about entity names
|
||||
and strings.
|
||||
|
||||
```clojure
|
||||
(sql/format {:select [[:column-name "some-alias"]]
|
||||
:from :b
|
||||
:order-by [[[:alias "some-alias"]]]})
|
||||
;;=> ["SELECT column_name AS \"some-alias\" FROM b ORDER BY \"some-alias\" ASC"]
|
||||
(sql/format {:select [[:column-name :'some-alias]]
|
||||
:from :b
|
||||
:order-by [[[:alias :'some-alias]]]})
|
||||
;;=> ["SELECT column_name AS \"some-alias\" FROM b ORDER BY \"some-alias\" ASC"]
|
||||
```
|
||||
|
||||
## array
|
||||
|
||||
Accepts a single argument, which is expected to evaluate to a sequence,
|
||||
|
|
@ -13,8 +38,6 @@ with an optional second argument specifying the type of the array,
|
|||
and produces `ARRAY[?, ?, ..]` for the elements of that sequence (as SQL parameters):
|
||||
|
||||
```clojure
|
||||
(require '[honey.sql :as sql])
|
||||
|
||||
(sql/format-expr [:array (range 5)])
|
||||
;;=> ["ARRAY[?, ?, ?, ?, ?]" 0 1 2 3 4]
|
||||
(sql/format-expr [:array (range 3) :text])
|
||||
|
|
|
|||
|
|
@ -2108,21 +2108,10 @@
|
|||
(sql/format {:insert-into :foo :output [:inserted.*] :values [{:bar 1}]})
|
||||
(sql/format {:insert-into :foo :columns [:bar] :output [:inserted.*] :values [[1]]})
|
||||
|
||||
;; issue-497
|
||||
(honey.sql/format {:select [[:column-name "some-alias"]]
|
||||
:from :b
|
||||
:order-by [[[:raw "\"some-alias\""]]]})
|
||||
(honey.sql/format {:select [[:column-name "some-alias"]]
|
||||
:from :b
|
||||
:order-by [[[:alias "some-alias"]]]})
|
||||
(honey.sql/format {:select [[:column-name "some-alias"]]
|
||||
:from :b
|
||||
:order-by [[[:alias "some-alias"]]]}
|
||||
{:quoted true})
|
||||
(honey.sql/format {:select [[:column-name "some-alias"]]
|
||||
:from :b
|
||||
:order-by [[[:alias "some-alias"]]]}
|
||||
{:dialect :mysql})
|
||||
(sql/format {:select [[:a.b :c.d]]} {:dialect :mysql})
|
||||
(sql/format {:select [[:column-name :'some-alias]]
|
||||
:from :b
|
||||
:order-by [[[:alias :'some-alias]]]})
|
||||
(sql/format {:select :f.* :from [[:foo [:f :FOR :SYSTEM-TIME]]] :where [:= :f.id 1]})
|
||||
(sql/format {:using [[:source [:= :table.id :source.id]]]})
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1205,6 +1205,45 @@ ORDER BY id = ? DESC
|
|||
(is (= ["INNER JOIN (tbl1 LEFT JOIN tbl2 USING (id))"]
|
||||
(sut/format {:join [[[:join :tbl1 {:left-join [:tbl2 [:using :id]]}]]]})))))
|
||||
|
||||
(deftest issue-497-alias
|
||||
|
||||
(is (= ["SELECT column_name AS \"some-alias\" FROM b ORDER BY \"some-alias\" ASC"]
|
||||
(sut/format {:select [[:column-name "some-alias"]]
|
||||
:from :b
|
||||
:order-by [[[:raw "\"some-alias\""]]]})))
|
||||
;; likely illegal SQL, but shows quoted keyword escaping the -/_ replace:
|
||||
(is (= ["SELECT column_name AS \"some-alias\" FROM b ORDER BY some-alias ASC"]
|
||||
(sut/format {:select [[:column-name "some-alias"]]
|
||||
:from :b
|
||||
:order-by [[:'some-alias]]})))
|
||||
(is (= ["SELECT column_name AS \"some-alias\" FROM b ORDER BY \"some-alias\" ASC"]
|
||||
(sut/format {:select [[:column-name "some-alias"]]
|
||||
:from :b
|
||||
:order-by [[[:alias "some-alias"]]]})))
|
||||
(is (= ["SELECT column_name AS \"some-alias\" FROM b ORDER BY some_alias ASC"]
|
||||
(sut/format {:select [[:column-name "some-alias"]]
|
||||
:from :b
|
||||
:order-by [[[:alias :some-alias]]]})))
|
||||
(is (= ["SELECT column_name AS \"some-alias\" FROM b ORDER BY \"some-alias\" ASC"]
|
||||
(sut/format {:select [[:column-name "some-alias"]]
|
||||
:from :b
|
||||
:order-by [[[:alias :'some-alias]]]})))
|
||||
(is (= ["SELECT column_name AS \"some-alias\" FROM b ORDER BY \"some-alias\" ASC"]
|
||||
(sut/format {:select [[:column-name "some-alias"]]
|
||||
:from :b
|
||||
:order-by [[[:alias "some-alias"]]]})))
|
||||
(is (= ["SELECT \"column-name\" AS \"some-alias\" FROM \"b\" ORDER BY ? ASC"
|
||||
"some-alias"]
|
||||
(sut/format {:select [[:column-name "some-alias"]]
|
||||
:from :b
|
||||
:order-by ["some-alias"]}
|
||||
{:quoted true})))
|
||||
(is (= ["SELECT `column-name` AS `some-alias` FROM `b` ORDER BY `some-alias` ASC"]
|
||||
(sut/format {:select [[:column-name "some-alias"]]
|
||||
:from :b
|
||||
:order-by [[[:alias "some-alias"]]]}
|
||||
{:dialect :mysql}))))
|
||||
|
||||
(comment
|
||||
;; partial workaround for #407:
|
||||
(sut/format {:select :f.* :from [[:foo [:f :for :system-time]]] :where [:= :f.id 1]})
|
||||
|
|
|
|||
Loading…
Reference in a new issue