Skip to content
Snippets Groups Projects
Unverified Commit 11884ebe authored by Cam Saul's avatar Cam Saul Committed by GitHub
Browse files

Merge pull request #9999 from metabase/new-joins-syntax

New joins syntax
parents 26d55530 f394b55b
No related merge requests found
......@@ -27,7 +27,7 @@
[toucan.util.test :as tt]))
(defn- rows+cols
"Return the `:rows` and relevant parts of `:cols` from the RESULTS.
"Return the `:rows` and relevant parts of `:cols` from the `results`.
(This is used to keep the output of various tests below focused and manageable.)"
{:style/indent 0}
[results]
......@@ -710,3 +710,18 @@
:filter [:=
[:field-literal (db/select-one-field :name Field :id $date) "type/DateTime"]
"2014-03-30"]}})))))
;; make sure filters in source queries are applied correctly!
(datasets/expect-with-drivers (qp.test/non-timeseries-drivers-with-feature :nested-queries :foreign-keys)
[["Fred 62" 1]
["Frolic Room" 1]]
(qp.test/format-rows-by [str int]
(qp.test/rows
(qp/process-query
(data/mbql-query checkins
{:source-query {:source-table $$checkins
:filter [:> $date "2015-01-01"]}
:aggregation [:count]
:order-by [[:asc $venue_id->venues.name]]
:breakout [$venue_id->venues.name]
:filter [:starts-with $venue_id->venues.name "F"]})))))
......@@ -101,14 +101,23 @@
[table-name body & {:keys [wrap-field-ids?], :or {wrap-field-ids? true}}]
(walk/postwalk
(fn [form]
(or (when (symbol? form)
(if (= form '$$table)
`(id ~(keyword table-name))
(let [[first-char & rest-chars] (name form)]
(when (= first-char \$)
(let [token (apply str rest-chars)]
(token->id-call wrap-field-ids? table-name token))))))
form))
(cond
(not (symbol? form))
form
(= form '$$table)
`(id ~(keyword table-name))
(str/starts-with? form "$$")
(let [table-name (str/replace form #"^\$\$" "")]
`(id ~(keyword table-name)))
(str/starts-with? form "$")
(let [field-name (str/replace form #"^\$" "")]
(token->id-call wrap-field-ids? table-name field-name))
:else
form))
body))
(defmacro $ids
......@@ -123,6 +132,10 @@
$$table -> (id :venues)
You can reference other tables by using `$$` as well:
$$categories -> (id :categories)
You can pass options by wrapping `table-name` in a vector:
($ids [venues {:wrap-field-ids? true}]
......@@ -136,16 +149,23 @@
(m/mapply $->id (keyword table-name) `(do ~@body) (merge {:wrap-field-ids? false}
options))))
(declare id)
(defn wrap-inner-mbql-query
"Wrap inner QUERY with `:database` ID and other 'outer query' kvs. DB ID is fetched by looking up the Database for
the query's `:source-table`."
{:style/indent 0}
[query]
{:database (db/select-one-field :db_id Table, :id (:source-table query))
{:database (id)
:type :query
:query query})
(defn add-source-table-if-needed [table query]
(if (and query
(some query #{:source-table :source-query}))
query
(assoc query :source-table (id table))))
(defmacro mbql-query
"Build a query, expands symbols like `$field` into calls to `id` and wraps them in `:field-id`. See the dox for
`$->id` for more information on how `$`-prefixed expansion behaves.
......@@ -160,8 +180,7 @@
{:style/indent 1}
[table & [query]]
`(wrap-inner-mbql-query
~(merge `{:source-table (id ~(keyword table))}
($->id table query))))
(add-source-table-if-needed ~(keyword table) ~($->id table query))))
(defmacro run-mbql-query
"Like `mbql-query`, but runs the query as well."
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment