diff --git a/src/metabase/lib/core.cljc b/src/metabase/lib/core.cljc index 849e36c9a5058feef115feb8af2e803f5b96e791..b1f7100d344efe47c5402986e1c442ff5b3fea80 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 6d11f6f8425438e028d002c31030e2d8766cbded..a8860c94eafb6ed2ca12aed54526bdf3f76199cf 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 74eafaebfbd74034f65993c01786df3ebb90f5c3..f8c6a59099e86aa2f6592a2b09db72f8a38090a5 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 ce32a2cb54619ead9662ebaca5322be5b32b1cc6..9a7885ccfc381bd8af8947591e72482ea3e7bdcc 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)))))))