From 522849381d550e90521eaf74e9573019b5a1892e Mon Sep 17 00:00:00 2001 From: Sean Corfield Date: Thu, 23 Mar 2023 20:49:34 -0700 Subject: [PATCH] fix #448 by adding database-specific hints and tips including sqlite :) --- CHANGELOG.md | 1 + doc/clause-reference.md | 3 +- doc/cljdoc.edn | 3 +- doc/databases.md | 83 +++++++++++++++++++++++++++++++++++++++ doc/extending-honeysql.md | 4 ++ doc/getting-started.md | 5 +++ 6 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 doc/databases.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a78b11..042bea3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ * 2.4.next in progress * Address [#481](https://github.com/seancorfield/honeysql/issues/481) by adding more examples around `:do-update-set`. * Address [#480](https://github.com/seancorfield/honeysql/issues/480) by clarifying the general relationship between clauses and helpers. + * Address [#448](https://github.com/seancorfield/honeysql/issues/448) by adding a new section with hints and tips for database-specific syntax and solutions. * 2.4.1006 -- 2023-03-17 * Fix [#478](https://github.com/seancorfield/honeysql/issues/478) by handling `:do-update-set` correctly in the `upsert` helper and by handling parameters correctly in the `:do-update-set` formatter. diff --git a/doc/clause-reference.md b/doc/clause-reference.md index d8e1b5b..a32a243 100644 --- a/doc/clause-reference.md +++ b/doc/clause-reference.md @@ -10,7 +10,8 @@ Clauses can be specified as keywords or symbols. Use a space (e.g., `:left-join` is formatted as `LEFT JOIN`). Except as noted, these clauses apply to all the SQL -dialects that HoneySQL supports. +dialects that HoneySQL supports. See also the section on +[database-specific hints and tips](databases.md). DDL clauses are listed first, followed by SQL clauses. diff --git a/doc/cljdoc.edn b/doc/cljdoc.edn index 2866ea6..03594f5 100644 --- a/doc/cljdoc.edn +++ b/doc/cljdoc.edn @@ -6,7 +6,8 @@ ["SQL Clause Reference" {:file "doc/clause-reference.md"}] ["SQL Operator Reference" {:file "doc/operator-reference.md"}] ["SQL 'Special Syntax'" {:file "doc/special-syntax.md"}] - ["PostgreSQL Support" {:file "doc/postgresql.md"}]] + ["PostgreSQL Support" {:file "doc/postgresql.md"}] + ["Other Databases" {:file "doc/databases.md"}]] ["All the Options" {:file "doc/options.md"}] ["Extending HoneySQL" {:file "doc/extending-honeysql.md"}] ["Differences from 1.x" {:file "doc/differences-from-1-x.md"}]]} diff --git a/doc/databases.md b/doc/databases.md new file mode 100644 index 0000000..01c2b3c --- /dev/null +++ b/doc/databases.md @@ -0,0 +1,83 @@ +# Other Databases + +There is a dedicated section for [PostgreSQL Support](postgres.md). +This section provides hints and tips for generating SQL for other +databases. + +As a reminder, HoneySQL supports the following dialects out of the box: +* `:ansi` -- which is the default and provides broad support for PostgreSQL as well +* `:mysql` -- which includes MariaDB and Percona +* `:oracle` +* `:sqlserver` -- Microsoft SQL Server + +For the most part, these dialects only change the "stropping" -- +how SQL entities are quoted in the generated SQL -- but dialects +can change clause order and/or add dialect-specific clauses. + +This section is a work-in-progress and more hints and tips will be +added over time for more databases. + +## Precedence + +The biggest difference between database dialects tends to be +precedence. MySQL actually has different precedence in the `SET` +clause but several databases disagree on the precedence of actual +"set" operations: `UNION`, `EXCEPT`, `INTERSECT`, etc. + +HoneySQL tries to be fairly neutral in this area and follows ANSI SQL +precedence. This means that some databases may have problems with +complex SQL operations that combine multiple clauses with contentious +precedence. In general, you can solve this using the `:nest` +pseudo-clause in the DSL: + + +```clojure +{:nest DSL} +;; will produce DSL wrapped in ( .. ) +``` + +This should allow you to cater to various databases' precedence +peculiarities. + +## BigQuery (Google) + +Function names can be case-sensitive: you can use the "as-is" notation +for SQL entities to avoid conversion to upper-case: `[:'domain :ref]` +produces `domain(ref)` rather than `DOMAIN(ref)`. + +## ClickHouse + +This is another case-sensitive database than requires the "as-is" +notation described for **BigQuery** above. + +`WITH expr AS ident` is supported as a core part of the DSL, +as of 2.4.962. + +## MySQL + +When you select the `:mysql` dialect, the precedence of `:set` is +changed. All the other databases get this correct. + +`REPLACE INTO`, while specific to MySQL and SQLite, is supported as +a core part of the DSL, as `:replace-into`, as of 2.4.969. + +## SQLite + +Precedence of "set" operations: SQLite differs from other databases +in handling compound SQL operations that use multiple `UNION`, +`EXCEPT`, `INTERSECT` clauses. Use `:nest` to disambiguate your +intentions. +See issue [#462](https://github.com/seancorfield/honeysql/issues/462) +for some background on this. + +`INSERT OR IGNORE INTO`: this syntax is specific to SQLite for +performing upserts. However, SQLite supports the PostgreSQL-style +upsert with `ON CONFLICT` so you can use that syntax instead, for +`DO NOTHING` and `DO UPDATE SET`. In addition, +`INSERT OR REPLACE INTO` can be written using just `REPLACE INTO` +(see below). +Issue [#448](https://github.com/seancorfield/honeysql/issues/448) +has more background on this. + +`REPLACE INTO`, while specific to MySQL and SQLite, is supported as +a core part of the DSL, as `:replace-into`, as of 2.4.969. diff --git a/doc/extending-honeysql.md b/doc/extending-honeysql.md index bf06655..5c8fe0b 100644 --- a/doc/extending-honeysql.md +++ b/doc/extending-honeysql.md @@ -14,6 +14,10 @@ many more. Built in operators include: `:=`, `:+`, `:mod`. Built in functions (special syntax) include: `:array`, `:case`, `:cast`, `:inline`, `:raw` and many more. +See also the section on +[database-specific hints and tips](databases.md), which may +let you avoid extending HoneySQL. + ## Extending what `:inline` can do By default, the `:inline` option can convert a fairly diff --git a/doc/getting-started.md b/doc/getting-started.md index a76cada..faf19d0 100644 --- a/doc/getting-started.md +++ b/doc/getting-started.md @@ -406,6 +406,11 @@ HoneySQL supports quite a few [PostgreSQL extensions](postgresql.md). > Note: the [nilenso/honeysql-postgres](https://github.com/nilenso/honeysql-postgres) library which provided PostgreSQL support for HoneySQL 1.x does not work with HoneySQL 2.x. However, HoneySQL 2.x includes all of the functionality from that library (up to 0.4.112) out of the box! +See also the section on +[database-specific hints and tips](databases.md) which may +provide ways to satisfy your database's needs without changing +the dialect or extending HoneySQL. + ## Reference Documentation The full list of supported SQL clauses is documented in the