Skip to content

Commit

Permalink
fix Support full TRUNCATE syntax (cascade, identity) #438
Browse files Browse the repository at this point in the history
  • Loading branch information
seancorfield committed Nov 5, 2022
1 parent dda3aa0 commit e8ea928
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Changes

* 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.
* 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!_
Expand Down
11 changes: 7 additions & 4 deletions doc/clause-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ order they would appear in a valid SQL statement).

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 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.
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.
Expand All @@ -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,
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
syntax of the pair is of the form `with expr AS ident` like this:

Expand All @@ -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"]
```

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:

```clojure
Expand Down Expand Up @@ -590,11 +590,14 @@ user=> (sql/format {:delete [:order :item]

## 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
user=> (sql/format '{truncate transport})
["TRUNCATE transport"]
user=> (sql/format '{truncate (transport restart identity)})
["TRUNCATE transport RESTART IDENTITY"]
```

## columns
Expand Down
25 changes: 20 additions & 5 deletions src/honey/sql.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -894,14 +894,14 @@
:else
(sql-kw opt))))

(defn- destructure-create-item [table context]
(defn- destructure-ddl-item [table context]
(let [params
(if (sequential? table)
table
[table])
tab? #(or (ident? %) (string? %))
coll (take-while tab? params)
opts (drop-while tab? params)
opts (filter some? (drop-while tab? params))
ine (last coll)
[prequel table ine]
(if (= :if-not-exists (sym->kw ine))
Expand All @@ -910,11 +910,26 @@
(into [(str/join " " (map sql-kw prequel))
(format-entity table)
(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]
(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?
(-> [(sql-kw q)
(when (and (= :create q) (seq pre)) pre)
Expand Down Expand Up @@ -1098,7 +1113,7 @@
:update (check-where #'format-selector)
:delete (check-where #'format-selects)
:delete-from (check-where #'format-selector)
:truncate #'format-selector
:truncate #'format-truncate
:columns #'format-columns
:set #'format-set-exprs
:from #'format-selects
Expand Down
3 changes: 3 additions & 0 deletions test/honey/sql_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,9 @@
(deftest truncate-test
(is (= ["TRUNCATE `foo`"]
(-> {:truncate :foo}
(format {:dialect :mysql}))))
(is (= ["TRUNCATE `foo` CONTINUE IDENTITY"]
(-> {:truncate [:foo :continue :identity]}
(format {:dialect :mysql})))))

(deftest inlined-values-are-stringified-correctly
Expand Down

0 comments on commit e8ea928

Please sign in to comment.