From b9b9c37dfac5b47507fb658ee777ba925bed72b3 Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Tue, 27 Sep 2016 18:16:33 -0700 Subject: [PATCH] Part 1: pass in :select when creating a partial subquery from a CC. --- src/common/datomish/query.cljc | 12 ++++----- src/common/datomish/query/clauses.cljc | 37 +++++++++++++++++--------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/common/datomish/query.cljc b/src/common/datomish/query.cljc index 8350bfaf..5501ffb9 100644 --- a/src/common/datomish/query.cljc +++ b/src/common/datomish/query.cljc @@ -63,13 +63,11 @@ (let [inner-projection (projection/sql-projection-for-relation context) inner (merge - {:select inner-projection - - ;; Always SELECT DISTINCT, because Datalog is set-based. - ;; TODO: determine from schema analysis whether we can avoid - ;; the need to do this. - :modifiers [:distinct]} - (clauses/cc->partial-subquery (:cc context))) + ;; Always SELECT DISTINCT, because Datalog is set-based. + ;; TODO: determine from schema analysis whether we can avoid + ;; the need to do this. + {:modifiers [:distinct]} + (clauses/cc->partial-subquery inner-projection (:cc context))) limit (:limit context) order-by (:order-by-vars context)] diff --git a/src/common/datomish/query/clauses.cljc b/src/common/datomish/query/clauses.cljc index eb27596d..bf9d5401 100644 --- a/src/common/datomish/query/clauses.cljc +++ b/src/common/datomish/query/clauses.cljc @@ -245,27 +245,38 @@ [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] (cc/expand-where-from-bindings (expand-pattern-clauses - (cc/map->ConjoiningClauses - {:source source - :from [] - :known-types (or known-types {}) - :extracted-types {} - :external-bindings (or external-bindings {}) - :bindings {} - :ctes {} - :wheres []}) + (make-cc source known-types external-bindings) patterns))) (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 subqueries and NOT EXISTS clauses." - [cc] + [select cc] (merge - {:from (:from cc)} + {:select select + :from (:from cc)} (when-not (empty? (:ctes cc)) {:with (:ctes cc)}) (when-not (empty? (:wheres cc)) @@ -296,7 +307,7 @@ (cons :and (:wheres (:cc not-join))) ;; 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