Reprioritize WITH wrt UNION and UNION ALL

WITH needs to come before clauses that are part of a UNION
or UNION ALL.[1][2][3][4]

[1] "A CTE must be followed by a single SELECT, INSERT, UPDATE, or DELETE
statement that references some or all the CTE columns."
https://docs.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql

[2] "the WITH clause itself is attached to a primary statement that can
also be a SELECT, INSERT, UPDATE, or DELETE"
https://www.postgresql.org/docs/9.6/static/queries-with.html

[3] https://mariadb.com/kb/en/mariadb/with/

[4] "All common table expressions (ordinary and recursive) are created
by prepending a WITH clause in front of a SELECT, INSERT, DELETE, or
UPDATE statement."
https://sqlite.org/lang_with.html

Added a test case demonstrating the expected behavior for each of
UNION and UNION ALL.
This commit is contained in:
Brandon Adams 2017-06-27 15:01:43 -05:00 committed by Michael Blume
parent 16251bf30d
commit f94e343f31
2 changed files with 19 additions and 4 deletions

View file

@ -183,10 +183,10 @@
(def default-clause-priorities
"Determines the order that clauses will be placed within generated SQL"
{:union 20
:union-all 25
:with 30
:with-recursive 40
{:with 20
:with-recursive 30
:union 40
:union-all 45
:select 50
:insert-into 60
:update 70

View file

@ -121,3 +121,18 @@
(format {:select [:foo]
:from [:bar]
:where [:= [:mod :col1 4] [:+ :col2 4]]})))))
(deftest union-with-cte
(is (= (format {:union [{:select [:foo] :from [:bar1]}
{:select [:foo] :from [:bar2]}]
:with [[[:bar {:columns [:spam :eggs]}]
{:values [[1 2] [3 4] [5 6]]}]]})
["WITH bar (spam, eggs) AS (VALUES (?, ?), (?, ?), (?, ?)) SELECT foo FROM bar1 UNION SELECT foo FROM bar2" 1 2 3 4 5 6])))
(deftest union-all-with-cte
(is (= (format {:union-all [{:select [:foo] :from [:bar1]}
{:select [:foo] :from [:bar2]}]
:with [[[:bar {:columns [:spam :eggs]}]
{:values [[1 2] [3 4] [5 6]]}]]})
["WITH bar (spam, eggs) AS (VALUES (?, ?), (?, ?), (?, ?)) SELECT foo FROM bar1 UNION ALL SELECT foo FROM bar2" 1 2 3 4 5 6])))