fix Support full TRUNCATE syntax (cascade, identity) #438

This commit is contained in:
Sean Corfield 2022-11-04 23:40:30 -07:00
parent dda3aa017e
commit e8ea9283cc
4 changed files with 32 additions and 9 deletions

View file

@ -1,6 +1,8 @@
# Changes # Changes
* 2.3.next in progress * 2.3.next in progress
* Fix [#438](https://github.com/seancorfield/honeysql/issues/438) by
supporting options on `TRUNCATE`.
* Address [#435](https://github.com/seancorfield/honeysql/issues/435) by showing `CREATE TEMP TABLE` etc. * Address [#435](https://github.com/seancorfield/honeysql/issues/435) by showing `CREATE TEMP TABLE` etc.
* Fix [#431](https://github.com/seancorfield/honeysql/issues/431). * Fix [#431](https://github.com/seancorfield/honeysql/issues/431).
* Address [#430](https://github.com/seancorfield/honeysql/issues/430) by treating `:'` as introducing a name that should be treating literally and not formatted as a SQL entity (which respects quoting, dot-splitting, etc); this effectively expands the "escape hatch" introduced via [#352](https://github.com/seancorfield/honeysql/issues/352) in 2.2.868. _Note that the function context behavior formats as a SQL entity, rather than the usual SQL "keyword", whereas this new context is a literal transcription rather than as a SQL entity!_ * Address [#430](https://github.com/seancorfield/honeysql/issues/430) by treating `:'` as introducing a name that should be treating literally and not formatted as a SQL entity (which respects quoting, dot-splitting, etc); this effectively expands the "escape hatch" introduced via [#352](https://github.com/seancorfield/honeysql/issues/352) in 2.2.868. _Note that the function context behavior formats as a SQL entity, rather than the usual SQL "keyword", whereas this new context is a literal transcription rather than as a SQL entity!_

View file

@ -321,7 +321,7 @@ order they would appear in a valid SQL statement).
These provide CTE support for SQL Server. The argument to These provide CTE support for SQL Server. The argument to
`:with` (or `:with-recursive`) is a sequences of pairs, each of `:with` (or `:with-recursive`) is a sequences of pairs, each of
a result set name (or description) and either of; a basic SQL a result set name (or description) and either of; a basic SQL
statement, a string, a keyword or a symbol. statement, a string, a keyword or a symbol.
The result set can either be a SQL entity (a simple name) 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. or a pair of a SQL entity and a set of column names.
@ -336,7 +336,7 @@ user=> (sql/format '{with ((stuff {select (:*) from (foo)}),
``` ```
When the expression is a basic SQL statement in any of the pairs, When the expression is a basic SQL statement in any of the pairs,
the resulting syntax of the pair is `with ident AS expr` as shown above. the resulting syntax of the pair is `with ident AS expr` as shown above.
However, when the expression is a string, a keyword or a symbol, the resulting However, when the expression is a string, a keyword or a symbol, the resulting
syntax of the pair is of the form `with expr AS ident` like this: syntax of the pair is of the form `with expr AS ident` like this:
@ -348,7 +348,7 @@ user=> (sql/format '{with ((ts_upper_bound "2019-08-01 15:23:00"))
["WITH ? AS ts_upper_bound SELECT * FROM hits WHERE EventDate = ts_upper_bound" "2019-08-01 15:23:00"] ["WITH ? AS ts_upper_bound SELECT * FROM hits WHERE EventDate = ts_upper_bound" "2019-08-01 15:23:00"]
``` ```
The syntax only varies for each pair and so you can use both SQL statements The syntax only varies for each pair and so you can use both SQL statements
and keywords/strings/symbols in the same WITH clause like this: and keywords/strings/symbols in the same WITH clause like this:
```clojure ```clojure
@ -590,11 +590,14 @@ user=> (sql/format {:delete [:order :item]
## truncate ## truncate
`:truncate` accepts a simple SQL entity (table name): `:truncate` accepts a simple SQL entity (table name)
or a table name followed by various options:
```clojure ```clojure
user=> (sql/format '{truncate transport}) user=> (sql/format '{truncate transport})
["TRUNCATE transport"] ["TRUNCATE transport"]
user=> (sql/format '{truncate (transport restart identity)})
["TRUNCATE transport RESTART IDENTITY"]
``` ```
## columns ## columns

View file

@ -894,14 +894,14 @@
:else :else
(sql-kw opt)))) (sql-kw opt))))
(defn- destructure-create-item [table context] (defn- destructure-ddl-item [table context]
(let [params (let [params
(if (sequential? table) (if (sequential? table)
table table
[table]) [table])
tab? #(or (ident? %) (string? %)) tab? #(or (ident? %) (string? %))
coll (take-while tab? params) coll (take-while tab? params)
opts (drop-while tab? params) opts (filter some? (drop-while tab? params))
ine (last coll) ine (last coll)
[prequel table ine] [prequel table ine]
(if (= :if-not-exists (sym->kw ine)) (if (= :if-not-exists (sym->kw ine))
@ -910,11 +910,26 @@
(into [(str/join " " (map sql-kw prequel)) (into [(str/join " " (map sql-kw prequel))
(format-entity table) (format-entity table)
(when ine (sql-kw ine))] (when ine (sql-kw ine))]
(format-ddl-options opts context)))) (when opts
(format-ddl-options opts context)))))
(defn- format-truncate [k xs]
(let [[table & options] (if (sequential? xs) xs [xs])
[pre table ine options] (destructure-ddl-item [table options] "truncate")]
(when (seq pre) (throw (ex-info "TRUNCATE syntax error" {:unexpected pre})))
(when (seq ine) (throw (ex-info "TRUNCATE syntax error" {:unexpected ine})))
[(str/join " " (cond-> [(sql-kw k) table]
(seq options)
(conj options)))]))
(comment
(destructure-ddl-item [:foo [:abc [:continue :wibble] :identity]] "test")
(destructure-ddl-item [:foo] "test")
(format-truncate :truncate [:foo]))
(defn- format-create [q k item as] (defn- format-create [q k item as]
(let [[pre entity ine & more] (let [[pre entity ine & more]
(destructure-create-item item (str (sql-kw q) " options"))] (destructure-ddl-item item (str (sql-kw q) " options"))]
[(str/join " " (remove nil? [(str/join " " (remove nil?
(-> [(sql-kw q) (-> [(sql-kw q)
(when (and (= :create q) (seq pre)) pre) (when (and (= :create q) (seq pre)) pre)
@ -1098,7 +1113,7 @@
:update (check-where #'format-selector) :update (check-where #'format-selector)
:delete (check-where #'format-selects) :delete (check-where #'format-selects)
:delete-from (check-where #'format-selector) :delete-from (check-where #'format-selector)
:truncate #'format-selector :truncate #'format-truncate
:columns #'format-columns :columns #'format-columns
:set #'format-set-exprs :set #'format-set-exprs
:from #'format-selects :from #'format-selects

View file

@ -519,6 +519,9 @@
(deftest truncate-test (deftest truncate-test
(is (= ["TRUNCATE `foo`"] (is (= ["TRUNCATE `foo`"]
(-> {:truncate :foo} (-> {:truncate :foo}
(format {:dialect :mysql}))))
(is (= ["TRUNCATE `foo` CONTINUE IDENTITY"]
(-> {:truncate [:foo :continue :identity]}
(format {:dialect :mysql}))))) (format {:dialect :mysql})))))
(deftest inlined-values-are-stringified-correctly (deftest inlined-values-are-stringified-correctly