Part 1: pass in :select when creating a partial subquery from a CC.

This commit is contained in:
Richard Newman 2016-09-27 18:16:33 -07:00
parent 1296b8090f
commit b9b9c37dfa
2 changed files with 29 additions and 20 deletions

View file

@ -63,13 +63,11 @@
(let [inner-projection (projection/sql-projection-for-relation context) (let [inner-projection (projection/sql-projection-for-relation context)
inner inner
(merge (merge
{:select inner-projection ;; Always SELECT DISTINCT, because Datalog is set-based.
;; TODO: determine from schema analysis whether we can avoid
;; Always SELECT DISTINCT, because Datalog is set-based. ;; the need to do this.
;; TODO: determine from schema analysis whether we can avoid {:modifiers [:distinct]}
;; the need to do this. (clauses/cc->partial-subquery inner-projection (:cc context)))
:modifiers [:distinct]}
(clauses/cc->partial-subquery (:cc context)))
limit (:limit context) limit (:limit context)
order-by (:order-by-vars context)] order-by (:order-by-vars context)]

View file

@ -245,27 +245,38 @@
[cc patterns] [cc patterns]
(reduce apply-clause cc patterns)) (reduce apply-clause cc patterns))
(defn- make-cc [source known-types external-bindings]
(cc/map->ConjoiningClauses
{:source source
:from []
:known-types (or known-types {})
:extracted-types {}
:external-bindings (or external-bindings {})
:bindings {}
:ctes {}
:wheres []}))
(defn pattern->cc [source pattern known-types external-bindings]
(cc/expand-where-from-bindings
(apply-clause
(make-cc source known-types external-bindings)
pattern)))
(defn patterns->cc [source patterns known-types external-bindings] (defn patterns->cc [source patterns known-types external-bindings]
(cc/expand-where-from-bindings (cc/expand-where-from-bindings
(expand-pattern-clauses (expand-pattern-clauses
(cc/map->ConjoiningClauses (make-cc source known-types external-bindings)
{:source source
:from []
:known-types (or known-types {})
:extracted-types {}
:external-bindings (or external-bindings {})
:bindings {}
:ctes {}
:wheres []})
patterns))) patterns)))
(defn cc->partial-subquery (defn cc->partial-subquery
"Build part of a honeysql query map from a CC: the `:from` and `:where` parts. "Build part of a honeysql query map from a CC: the `:select`, `:from`, and
`:where` parts.
This allows for reuse both in top-level query generation and also for This allows for reuse both in top-level query generation and also for
subqueries and NOT EXISTS clauses." subqueries and NOT EXISTS clauses."
[cc] [select cc]
(merge (merge
{:from (:from cc)} {:select select
:from (:from cc)}
(when-not (empty? (:ctes cc)) (when-not (empty? (:ctes cc))
{:with (:ctes cc)}) {:with (:ctes cc)})
(when-not (empty? (:wheres cc)) (when-not (empty? (:wheres cc))
@ -296,7 +307,7 @@
(cons :and (:wheres (:cc not-join))) (cons :and (:wheres (:cc not-join)))
;; If it does establish bindings, then it has to be a subquery. ;; If it does establish bindings, then it has to be a subquery.
[:exists (merge {:select [1]} (cc->partial-subquery (:cc not-join)))])]) [:exists (cc->partial-subquery [1] (:cc not-join))])])
;; A simple Or clause is one in which each branch can be evaluated against ;; A simple Or clause is one in which each branch can be evaluated against