From d95361572729672f9fc0484db9df6d62596f5a19 Mon Sep 17 00:00:00 2001 From: Niels van Klaveren Date: Tue, 19 Aug 2014 11:11:09 +0200 Subject: [PATCH] Added OVER (PARTITION BY) clause Supports windowed aggregate functions as fields {:aggregate :%fn.field :over {:partition-by [:field]}} --- src/honeysql/format.clj | 14 ++++++++++++-- src/honeysql/helpers.clj | 23 +++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/honeysql/format.clj b/src/honeysql/format.clj index 004a640..14bc31e 100644 --- a/src/honeysql/format.clj +++ b/src/honeysql/format.clj @@ -157,8 +157,8 @@ (def clause-order "Determines the order that clauses will be placed within generated SQL" [:select :insert-into :update :delete-from :columns :set :from :join - :left-join :right-join :where :group-by :having :order-by :limit :offset - :values :query-values]) + :left-join :right-join :where :aggregate :over :partition-by :group-by + :having :order-by :limit :offset :values :query-values]) (def known-clauses (set clause-order)) @@ -386,3 +386,13 @@ (defmethod format-clause :delete-from [[_ table] _] (str "DELETE FROM " (to-sql table))) + +(defmethod format-clause :over [[_ part-clause] _] + (str "OVER " (to-sql part-clause))) + +(defmethod format-clause :aggregate [[_ aggregate-fn] _] + (str (to-sql aggregate-fn))) + +(defmethod format-clause :partition-by [[_ fields] _] + (str "PARTITION BY " + (comma-join (map to-sql fields)))) diff --git a/src/honeysql/helpers.clj b/src/honeysql/helpers.clj index 91c1ca2..a0333de 100644 --- a/src/honeysql/helpers.clj +++ b/src/honeysql/helpers.clj @@ -209,3 +209,26 @@ (defn delete-from ([table] (delete-from nil table)) ([m table] (build-clause :delete-from m table))) + +(defmethod build-clause :over [_ m table] + (assoc m :over table)) + +(defn over + ([part-clause] (over nil part-clause)) + ([m part-clause] (build-clause :over m part-clause))) + +(defhelper merge-over [m fields] + (update-in m [:over] (partial apply merge) (collify fields))) + +(defhelper aggregate [m aggregate-fn] + (assoc m :aggregate aggregate-fn)) + +(defn aggregate + ([table] (aggregate nil table)) + ([m table] (build-clause :aggregate m table))) + +(defhelper spartition-by [m fields] + (assoc m :partition-by (collify fields))) + +(defhelper merge-partition-by [m fields] + (update-in m [:partition-by] concat (collify fields)))