-
Notifications
You must be signed in to change notification settings - Fork 4.9k
/
limit.clj
42 lines (37 loc) · 1.27 KB
/
limit.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
(ns metabase.query-processor.middleware.limit
"Middleware that handles limiting the maximum number of rows returned by a query."
(:require [metabase.mbql.util :as mbql.u]
[metabase.query-processor
[interface :as i]
[util :as qputil]]))
(defn- add-limit [max-rows {query-type :type, :as query}]
(cond-> query
(and (= query-type :query)
(qputil/query-without-aggregations-or-limits? query))
(assoc-in [:query :limit] max-rows)))
(defn- limit-xform [max-rows rf]
{:pre [(fn? rf)]}
(let [row-count (volatile! 0)]
(fn
([]
(rf))
([result]
(rf result))
([result row]
(let [result' (rf result row)
new-row-count (vswap! row-count inc)]
(if (>= new-row-count max-rows)
(ensure-reduced result')
result'))))))
(defn limit
"Add an implicit `limit` clause to MBQL queries without any aggregations, and limit the maximum number of rows that
can be returned in post-processing."
[qp]
(fn [query rff context]
(let [max-rows (or (mbql.u/query->max-rows-limit query)
i/absolute-max-results)]
(qp
(add-limit max-rows query)
(fn [metadata]
(limit-xform max-rows (rff metadata)))
context))))