From 202322f93d91b71e62b59534c1e2fb9a5b6023a5 Mon Sep 17 00:00:00 2001 From: Kamil Mielnik <kamil@kamilmielnik.com> Date: Tue, 26 Nov 2024 23:48:21 +0700 Subject: [PATCH] Add stage-number parameter to NativeParameterDimensionTarget (#50494) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add stage-number parameter to NativeParameterDimensionTarget * Update unit test * Recognize native query dimension parameters with stage-number * Update test setup --------- Co-authored-by: Tamás Benkő <tamas@metabase.com> --- .../dashboard-filters/parameters.cy.spec.js | 6 +++++- .../v1/parameters/utils/targets.ts | 3 ++- .../parameters/utils/mapping-options.ts | 6 ++++-- .../utils/mapping-options.unit.spec.js | 6 +++++- .../driver/common/parameters/values.clj | 19 +++++++++++++++++-- 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/e2e/test/scenarios/dashboard-filters/parameters.cy.spec.js b/e2e/test/scenarios/dashboard-filters/parameters.cy.spec.js index f5ec58ddb9d..b88bfb94274 100644 --- a/e2e/test/scenarios/dashboard-filters/parameters.cy.spec.js +++ b/e2e/test/scenarios/dashboard-filters/parameters.cy.spec.js @@ -298,7 +298,11 @@ describe("scenarios > dashboard > parameters", () => { { parameter_id: matchingFilterType.id, card_id, - target: ["dimension", ["template-tag", "filter"]], + target: [ + "dimension", + ["template-tag", "filter"], + { "stage-number": 0 }, + ], }, ], }, diff --git a/frontend/src/metabase-lib/v1/parameters/utils/targets.ts b/frontend/src/metabase-lib/v1/parameters/utils/targets.ts index fb3f8eb5fc7..d249f819a1e 100644 --- a/frontend/src/metabase-lib/v1/parameters/utils/targets.ts +++ b/frontend/src/metabase-lib/v1/parameters/utils/targets.ts @@ -127,8 +127,9 @@ export function getParameterTargetField( export function buildDimensionTarget( dimension: TemplateTagDimension, + stageIndex: number, ): NativeParameterDimensionTarget { - return ["dimension", dimension.mbql()]; + return ["dimension", dimension.mbql(), { "stage-number": stageIndex }]; } export function buildColumnTarget( diff --git a/frontend/src/metabase/parameters/utils/mapping-options.ts b/frontend/src/metabase/parameters/utils/mapping-options.ts index 4bc142f0d78..83aa8ac02f1 100644 --- a/frontend/src/metabase/parameters/utils/mapping-options.ts +++ b/frontend/src/metabase/parameters/utils/mapping-options.ts @@ -64,6 +64,7 @@ function buildStructuredQuerySectionOptions( function buildNativeQuerySectionOptions( section: DimensionOptionsSection, + stageIndex: number, ): NativeParameterMappingOption[] { return section.items .flatMap(({ dimension }) => @@ -73,7 +74,7 @@ function buildNativeQuerySectionOptions( name: dimension.displayName(), icon: dimension.icon() ?? "", isForeign: false, - target: buildDimensionTarget(dimension), + target: buildDimensionTarget(dimension, stageIndex), })); } @@ -184,6 +185,7 @@ export function getParameterMappingOptions( const legacyQuery = question.legacyQuery(); const options: NativeParameterMappingOption[] = []; + const stageIndex = Lib.stageCount(question.query()) - 1; options.push( ...legacyQuery @@ -196,7 +198,7 @@ export function getParameterMappingOptions( parameter ? dimensionFilterForParameter(parameter) : undefined, ) .sections() - .flatMap(section => buildNativeQuerySectionOptions(section)), + .flatMap(section => buildNativeQuerySectionOptions(section, stageIndex)), ); return options; diff --git a/frontend/src/metabase/parameters/utils/mapping-options.unit.spec.js b/frontend/src/metabase/parameters/utils/mapping-options.unit.spec.js index 5b5ef144dd4..d365641447b 100644 --- a/frontend/src/metabase/parameters/utils/mapping-options.unit.spec.js +++ b/frontend/src/metabase/parameters/utils/mapping-options.unit.spec.js @@ -357,7 +357,11 @@ describe("parameters/utils/mapping-options", () => { { name: "Created At", icon: "calendar", - target: ["dimension", ["template-tag", "created"]], + target: [ + "dimension", + ["template-tag", "created"], + { "stage-number": 0 }, + ], isForeign: false, }, ]); diff --git a/src/metabase/driver/common/parameters/values.clj b/src/metabase/driver/common/parameters/values.clj index 6bb9c977f71..2b88639b16f 100644 --- a/src/metabase/driver/common/parameters/values.clj +++ b/src/metabase/driver/common/parameters/values.clj @@ -95,13 +95,28 @@ #{[target-type [:template-tag (:name tag)]] [target-type [:template-tag {:id (:id tag)}]]})) +(defn- tag-target-pred + "Returns a predicate recognizing parameter targets pointing to `tag`." + [tag] + (let [targets (tag-targets tag)] + (fn tag-target? [param-target] + (and (vector? param-target) + (> (count param-target) 1) + (targets (subvec param-target 0 2)) + ;; legacy dimension params come without stage-number, 0 is the default + (= (get-in param-target [2 :stage-number] 0) + ;; Currently, we have no multi-stage native queries, so the stage-number is always 0. + ;; If in the future we introduce such queries, we can specify the stage-number of tags + ;; and they should match the stage-number of the parameter target. + (get tag :stage-number 0)))))) + (mu/defn- tag-params "Return params from the provided `params` list targeting the provided `tag`." [tag :- mbql.s/TemplateTag params :- [:maybe [:sequential mbql.s/Parameter]]] - (let [targets (tag-targets tag)] + (let [tag-target? (tag-target-pred tag)] (seq (for [param params - :when (contains? targets (:target param))] + :when (tag-target? (:target param))] param)))) ;;; FieldFilter Params (Field Filters) (e.g. WHERE {{x}}) -- GitLab