Skip to content
Snippets Groups Projects
Unverified Commit 435d823a authored by Braden Shepherdson's avatar Braden Shepherdson Committed by GitHub
Browse files

[MBQL lib] Add `Lib.extractionExpression` to get the expression directly (#41885)

Previously they could only be added to the query with `Lib.extract`, but
this returns the expression the extract would add.
parent dd0f14a5
No related branches found
No related tags found
No related merge requests found
......@@ -22,8 +22,9 @@ and documented in this changelog.
`as-returned` looks at the query and stage, and shifts to a later stage if necessary. If a later stage is needed but
we were already on the last stage, a new empty stage is appended.
- New functions `column-extractions` and `extract` have been added.
- New functions `column-extractions`, `extract`, and `extraction-expression` have been added.
- `column-extractions` returns a list of _extractions_, which are possible custom expressions we can derive from a
given column. For example, getting the host or base domain name from a URL or email address, or the day of the week
from a date or datetime.
- `extract` applies an extraction to the query.
- `extraction-expression` returns the expression for the extraction, allowing further editing.
......@@ -176,7 +176,8 @@
offset]
[lib.extraction
column-extractions
extract]
extract
extraction-expression]
[lib.fe-util
dependent-metadata
expression-clause
......
......@@ -4,6 +4,7 @@
[metabase.lib.metadata :as lib.metadata]
[metabase.lib.metadata.calculation :as lib.metadata.calculation]
[metabase.lib.schema :as lib.schema]
[metabase.lib.schema.expression :as lib.schema.expression]
[metabase.lib.schema.extraction :as lib.schema.extraction]
[metabase.lib.schema.metadata :as lib.schema.metadata]
[metabase.lib.temporal-bucket :as lib.temporal-bucket]
......@@ -77,7 +78,11 @@
[_query _stage-number extraction]
(dissoc extraction :lib/type :column))
(defn- extraction-expression [column tag]
(mu/defn extraction-expression :- ::lib.schema.expression/expression
"Given an `extraction` as returned by [[column-extractions]], return the expression clause that should be added to a
query."
[{:keys [column tag] :as _expression} :- ::lib.schema.extraction/extraction
]
(case tag
;; Temporal extractions
:hour-of-day (lib.expression/get-hour column)
......@@ -93,9 +98,9 @@
(mu/defn extract :- ::lib.schema/query
"Given a query, stage and extraction as returned by [[column-extractions]], apply that extraction to the query."
[query :- ::lib.schema/query
stage-number :- :int
{:keys [column display-name tag]} :- ::lib.schema.extraction/extraction]
[query :- ::lib.schema/query
stage-number :- :int
{:keys [display-name] :as extraction} :- ::lib.schema.extraction/extraction]
;; Currently this is very simple: use the `:tag` as an expression function and the column as the only argument.
(let [unique-name-fn (->> (lib.util/query-stage query stage-number)
(lib.metadata.calculation/returned-columns query stage-number)
......@@ -105,4 +110,4 @@
query
stage-number
(unique-name-fn display-name)
(extraction-expression column tag))))
(extraction-expression extraction))))
......@@ -1384,6 +1384,15 @@
[a-query stage-number extraction]
(lib.core/extract a-query stage-number extraction))
(defn ^:export extraction-expression
"Given `a-query` and an `extraction`, returns the expression it represents, as an opaque form similarly to
[[expression-clause]]. It can be passed to [[expression]] to add it to the query. (Though if that's all you need, use
[[extract]] instead.)
> **Code health:** Healthy"
[_a-query _stage-number extraction]
(lib.core/extraction-expression extraction))
(defn ^:export suggested-join-conditions
"Returns a JS array of possible default join conditions when joining against `joinable`, e.g. a Table, Saved
Question, or another query. Suggested conditions will be returned if the existing query has a foreign key to the
......
......@@ -23,16 +23,22 @@
{:tag :year, :column created-at, :display-name "Year"}]
extractions))
(testing "extracting :month-of-year"
(is (=? [:month-name {} [:get-month {} [:field {} (meta/id :orders :created-at)]]]
(lib/extraction-expression (:month-of-year by-tag))))
(is (=? {:stages [{:expressions
[[:month-name {:lib/expression-name "Month of year"}
[:get-month {} [:field {} (meta/id :orders :created-at)]]]]}]}
(lib/extract query -1 (:month-of-year by-tag)))))
(testing "extracting :day-of-week"
(is (=? [:day-name {} [:get-day-of-week {} [:field {} (meta/id :orders :created-at)]]]
(lib/extraction-expression (:day-of-week by-tag))))
(is (=? {:stages [{:expressions
[[:day-name {:lib/expression-name "Day of week"}
[:get-day-of-week {} [:field {} (meta/id :orders :created-at)]]]]}]}
(lib/extract query -1 (:day-of-week by-tag)))))
(testing "extracting :quarter-of-year"
(is (=? [:quarter-name {} [:get-quarter {} [:field {} (meta/id :orders :created-at)]]]
(lib/extraction-expression (:quarter-of-year by-tag))))
(is (=? {:stages [{:expressions
[[:quarter-name {:lib/expression-name "Quarter of year"}
[:get-quarter {} [:field {} (meta/id :orders :created-at)]]]]}]}
......@@ -41,6 +47,8 @@
[:day-of-month :get-day "Day of month"]
[:hour-of-day :get-hour "Hour of day"]]]
(testing (str "extracting " tag)
(is (=? [expr {} [:field {} (meta/id :orders :created-at)]]
(lib/extraction-expression (get by-tag tag))))
(is (=? {:stages [{:expressions [[expr {:lib/expression-name label}
[:field {} (meta/id :orders :created-at)]]]}]}
(lib/extract query -1 (get by-tag tag)))))))))
......@@ -128,14 +136,20 @@
by-tag (m/index-by :tag extractions)]
(is (=? #{:domain :subdomain :host} (set (keys by-tag))))
(testing "to :domain"
(is (=? [:domain {} [:field {} 9999001]]
(lib/extraction-expression (:domain by-tag))))
(is (=? {:stages [{:expressions [[:domain {:lib/expression-name "Domain"}
[:field {} 9999001]]]}]}
(lib/extract query -1 (:domain by-tag)))))
(testing "to :subdomain"
(is (=? [:subdomain {} [:field {} 9999001]]
(lib/extraction-expression (:subdomain by-tag))))
(is (=? {:stages [{:expressions [[:subdomain {:lib/expression-name "Subdomain"}
[:field {} 9999001]]]}]}
(lib/extract query -1 (:subdomain by-tag)))))
(testing "to :host"
(is (=? [:host {} [:field {} 9999001]]
(lib/extraction-expression (:host by-tag))))
(is (=? {:stages [{:expressions [[:host {:lib/expression-name "Host"}
[:field {} 9999001]]]}]}
(lib/extract query -1 (:host by-tag))))))))
......
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