Skip to content
Snippets Groups Projects
Unverified Commit febfe4a5 authored by Case Nelson's avatar Case Nelson Committed by GitHub
Browse files

[Metrics V2] Metrics with filters on implicitly joined columns produce query...

[Metrics V2] Metrics with filters on implicitly joined columns produce query error when added in a Summarize block (#43987)

* [Metrics V2] Metrics with filters on implicitly joined columns produce query error when added in a Summarize block

* Handle multiple metrics with same implicit join

* Address PR feedback
parent 9ebb679f
Branches
Tags
No related merge requests found
......@@ -91,6 +91,16 @@
stage-path (lib.walk/query-for-path stage-path)
stage-path :query))
(defn- include-implicit-joins
[query metric-query]
(let [metric-joins (lib/joins metric-query 0)
existing-joins (into #{}
(map (juxt :fk-field-id :alias))
(lib/joins query 0))]
(reduce #(lib/join %1 0 %2)
query
(remove (comp existing-joins (juxt :fk-field-id :alias)) metric-joins))))
(defn splice-compatible-metrics
"Splices in metric definitions that are compatible with the query."
[query path expanded-stages]
......@@ -108,6 +118,7 @@
(let [metric-query (update-metric-query-expression-names metric-query unique-name-fn)]
(as-> query $q
(reduce expression-with-name-from-source $q (lib/expressions metric-query 0))
(include-implicit-joins $q metric-query)
(reduce #(lib/filter %1 0 %2) $q (lib/filters metric-query 0))
(replace-metric-aggregation-refs $q 0 lookup)))
(throw (ex-info "Incompatible metric" {:query query
......
......@@ -89,6 +89,66 @@
:aggregation [[:+ {} [:avg {} [:field {} (meta/id :products :rating)]] 1]]}]}
(adjust query)))))
(deftest ^:parallel metric-with-implicit-join-test
(testing "Metrics with filters on implicitly joined columns should work #43943"
(let [[source-metric mp] (mock-metric (as-> (lib/query meta/metadata-provider (meta/table-metadata :orders)) $q
(lib/filter $q (lib/= (m/find-first (comp #{(meta/id :products :category)} :id) (lib/filterable-columns $q)) "Gadget"))
(lib/aggregate $q (lib/count))))
query (-> (lib/query mp (meta/table-metadata :orders))
(lib/aggregate (lib.options/ensure-uuid [:metric {} (:id source-metric)])))]
(is (=?
{:stages [{:source-table (meta/id :orders)
:joins [{:stages [{:source-table (meta/id :products)}]}]
:filters [[:= {} [:field {} (meta/id :products :category)] [:value {} "Gadget"]]]
:aggregation [[:count {}]]}]}
(adjust query)))
(testing "With an explicit product join in consumer query"
(is (=?
{:stages [{:source-table (meta/id :orders)
:joins [{:stages [{:source-table (meta/id :products)}]}
{:stages [{:source-table (meta/id :products)}]}]
:filters [[:= {} [:field {} (meta/id :products :title)] "foobar"]
[:= {} [:field {} (meta/id :products :category)] [:value {} "Gadget"]]]
:aggregation [[:count {}]]}]}
(adjust (as-> (lib/query mp (meta/table-metadata :orders)) $q
(lib/join $q (meta/table-metadata :products))
(lib/filter $q (lib/= (m/find-first (comp #{(meta/id :products :title)} :id) (lib/filterable-columns $q))
"foobar"))
(lib/aggregate $q (lib.options/ensure-uuid [:metric {} (:id source-metric)])))))))
(testing "With an implicit product join in consumer query"
(is (=?
{:stages [{:source-table (meta/id :orders)
:joins [{:stages [{:source-table (meta/id :products)}]}]
:filters [[:= {} [:field {} (meta/id :products :title)] "foobar"]
[:= {} [:field {} (meta/id :products :category)] [:value {} "Gadget"]]]
:aggregation [[:count {}]]}]}
(adjust (as-> (lib/query mp (meta/table-metadata :orders)) $q
(lib/filter $q (lib/= (m/find-first (comp #{(meta/id :products :title)} :id) (lib/filterable-columns $q))
"foobar"))
(lib/aggregate $q (lib.options/ensure-uuid [:metric {} (:id source-metric)]))))))))))
(deftest ^:parallel multiple-source-metrics-with-implicit-join-test
(let [[first-metric mp] (mock-metric (as-> (lib/query meta/metadata-provider (meta/table-metadata :orders)) $q
(lib/filter $q (lib/= (m/find-first (comp #{(meta/id :products :category)} :id)
(lib/filterable-columns $q))
"Gadget"))
(lib/aggregate $q (lib/count))))
[second-metric mp] (mock-metric mp (as-> (lib/query mp (meta/table-metadata :orders)) $q
(lib/filter $q (lib/= (m/find-first (comp #{(meta/id :products :title)} :id)
(lib/filterable-columns $q))
"Title"))
(lib/aggregate $q (lib/count))))
query (-> (lib/query mp (meta/table-metadata :orders))
(lib/aggregate (lib.options/ensure-uuid [:metric {} (:id first-metric)]))
(lib/aggregate (lib.options/ensure-uuid [:metric {} (:id second-metric)])))]
(is (=? {:stages [{:source-table (meta/id :orders)
:joins [{:stages [{:source-table (meta/id :products)}]}]
:filters [[:= {} [:field {} (meta/id :products :category)] [:value {} "Gadget"]]
[:= {} [:field {} (meta/id :products :title)] [:value {} "Title"]]]
:aggregation [[:count {}]
[:count {}]]}]}
(adjust query)))))
(deftest ^:parallel adjust-aggregation-metric-ordering-test
(let [[source-metric mp] (mock-metric)
query (-> (lib/query mp (meta/table-metadata :products))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment