From cb6a6849e447900cd867a9b307872bb2de6d2ffb Mon Sep 17 00:00:00 2001 From: Case Nelson <case@metabase.com> Date: Tue, 28 Mar 2023 21:03:13 -0600 Subject: [PATCH] [MLv2] Append and drop final stage (#29625) * [MLv2] Append and drop final stage * Address review * order-bys can return nil * Check exceptions differently in cljs --- src/metabase/lib/core.cljc | 3 +++ src/metabase/lib/order_by.cljc | 2 +- src/metabase/lib/stage.cljc | 13 +++++++++++++ test/metabase/lib/stage_test.cljc | 14 ++++++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/metabase/lib/core.cljc b/src/metabase/lib/core.cljc index 849e36c9a50..b1f7100d344 100644 --- a/src/metabase/lib/core.cljc +++ b/src/metabase/lib/core.cljc @@ -145,5 +145,8 @@ native-query query saved-question-query] + [lib.stage + append-stage + drop-stage] [lib.temporal-bucket temporal-bucket]) diff --git a/src/metabase/lib/order_by.cljc b/src/metabase/lib/order_by.cljc index 6d11f6f8425..a8860c94eaf 100644 --- a/src/metabase/lib/order_by.cljc +++ b/src/metabase/lib/order_by.cljc @@ -87,7 +87,7 @@ (lib.util/update-query-stage query stage-number update :order-by (fn [order-bys] (conj (vec order-bys) new-order-by)))))) -(mu/defn order-bys :- [:sequential ::lib.schema.order-by/order-by] +(mu/defn order-bys :- [:maybe [:sequential ::lib.schema.order-by/order-by]] "Get the order-by clauses in a query." ([query :- ::lib.schema/query] (order-bys query -1)) diff --git a/src/metabase/lib/stage.cljc b/src/metabase/lib/stage.cljc index 74eafaebfbd..f8c6a59099e 100644 --- a/src/metabase/lib/stage.cljc +++ b/src/metabase/lib/stage.cljc @@ -8,6 +8,7 @@ [metabase.lib.expression :as lib.expression] [metabase.lib.metadata :as lib.metadata] [metabase.lib.metadata.calculation :as lib.metadata.calculation] + [metabase.lib.options :as lib.options] [metabase.lib.schema :as lib.schema] [metabase.lib.schema.common :as lib.schema.common] [metabase.lib.schema.id :as lib.schema.id] @@ -248,3 +249,15 @@ (lib.expression/expressions query stage-number) columns (implicitly-joinable-columns query columns)))) + +(mu/defn append-stage :- ::lib.schema/query + "Adds a new blank stage to the end of the pipeline" + [query] + (update query :stages conj (lib.options/ensure-uuid {:lib/type :mbql.stage/mbql}))) + +(mu/defn drop-stage :- ::lib.schema/query + "Drops the final stage in the pipeline" + [query] + (when (= 1 (count (:stages query))) + (throw (ex-info (i18n/tru "Cannot drop the only stage") {:stages (:stages query)}))) + (update query :stages (comp vec butlast))) diff --git a/test/metabase/lib/stage_test.cljc b/test/metabase/lib/stage_test.cljc index ce32a2cb546..9a7885ccfc3 100644 --- a/test/metabase/lib/stage_test.cljc +++ b/test/metabase/lib/stage_test.cljc @@ -64,3 +64,17 @@ :source-table "card__1"}]}] (is (= "My Card" (lib.metadata.calculation/display-name query -1 query))))) + +(deftest ^:parallel adding-and-removing-stages + (let [query (lib/query-for-table-name meta/metadata-provider "VENUES") + query-with-new-stage (-> query + lib/append-stage + (lib/order-by 1 (lib/field "VENUES" "NAME") :asc))] + (is (= 0 (count (lib/order-bys query-with-new-stage 0)))) + (is (= 1 (count (lib/order-bys query-with-new-stage 1)))) + (is (= query + (-> query-with-new-stage + (lib/filter (lib/= 1 (lib/field "VENUES" "NAME"))) + (lib/drop-stage)))) + (testing "Dropping with 1 stage should error" + (is (thrown-with-msg? #?(:cljs :default :clj Exception) #"Cannot drop the only stage" (-> query (lib/drop-stage))))))) -- GitLab