From 9a9216fc8ba31673dfe4846308a100fc87095dfb Mon Sep 17 00:00:00 2001 From: metamben <103100869+metamben@users.noreply.github.com> Date: Thu, 24 Aug 2023 20:49:55 +0300 Subject: [PATCH] Add find-visible-column-for-legacy-ref (#33447) --- frontend/src/metabase-lib/fields.ts | 9 +++++++++ src/metabase/lib/core.cljc | 1 + src/metabase/lib/field.cljc | 15 ++++++++++++++ src/metabase/lib/js.cljs | 9 +++++++++ test/metabase/lib/field_test.cljc | 31 +++++++++++++++++++++++++++++ 5 files changed, 65 insertions(+) diff --git a/frontend/src/metabase-lib/fields.ts b/frontend/src/metabase-lib/fields.ts index dc7f188a91a..dc5f52b2c1d 100644 --- a/frontend/src/metabase-lib/fields.ts +++ b/frontend/src/metabase-lib/fields.ts @@ -1,4 +1,5 @@ import * as ML from "cljs/metabase.lib.js"; +import type { FieldReference } from "metabase-types/api"; import type { Clause, ColumnMetadata, Query } from "./types"; export function fields(query: Query, stageIndex: number): Clause[] { @@ -30,3 +31,11 @@ export function fieldableColumns( export function _fieldId(column: ColumnMetadata): number | null { return ML.field_id(column); } + +export function findVisibleColumnForLegacyRef( + query: Query, + stageIndex: number, + fieldRef: FieldReference, +): ColumnMetadata | null { + return ML.find_visible_column_for_legacy_ref(query, stageIndex, fieldRef); +} diff --git a/src/metabase/lib/core.cljc b/src/metabase/lib/core.cljc index 3e5e9821d89..ae0befbcefe 100644 --- a/src/metabase/lib/core.cljc +++ b/src/metabase/lib/core.cljc @@ -148,6 +148,7 @@ field-id fieldable-columns fields + find-visible-column-for-ref remove-field with-fields] [lib.filter diff --git a/src/metabase/lib/field.cljc b/src/metabase/lib/field.cljc index d6303d83c24..d303edcef8b 100644 --- a/src/metabase/lib/field.cljc +++ b/src/metabase/lib/field.cljc @@ -705,3 +705,18 @@ :source/native (throw (ex-info (native-query-fields-edit-error) {:query query :stage stage-number})) ;; Default case: do nothing and return the query unchaged. query))) + +(mu/defn find-visible-column-for-ref :- [:maybe lib.metadata/ColumnMetadata] + "Return the visible column in `query` at `stage-number` referenced by `field-ref`. + If `stage-number` is omitted, the last stage is used." + ([query field-ref] + (find-visible-column-for-ref query -1 field-ref)) + + ([query :- ::lib.schema/query + stage-number :- :int + field-ref] + (let [stage (lib.util/query-stage query stage-number) + columns (lib.metadata.calculation/visible-columns query stage-number stage) + ref->col (zipmap (map lib.ref/ref columns) columns) + col-ref (lib.equality/find-closest-matching-ref query field-ref (keys ref->col))] + (ref->col col-ref)))) diff --git a/src/metabase/lib/js.cljs b/src/metabase/lib/js.cljs index ef5966fc96e..ed78f6e11ca 100644 --- a/src/metabase/lib/js.cljs +++ b/src/metabase/lib/js.cljs @@ -427,6 +427,15 @@ [a-query stage-number column] (lib.core/remove-field a-query stage-number column)) +(defn ^:export find-visible-column-for-legacy-ref + "Return the visible column in `a-query` at `stage-number` referenced by `legacy-ref`." + [a-query stage-number legacy-ref] + (let [ref (-> legacy-ref + (js->clj :keywordize-keys true) + (update 0 keyword) + convert/->pMBQL)] + (lib.core/find-visible-column-for-ref a-query stage-number ref))) + (defn ^:export join-strategy "Get the strategy (type) of a given join as an opaque JoinStrategy object." [a-join] diff --git a/test/metabase/lib/field_test.cljc b/test/metabase/lib/field_test.cljc index 32284d50d6a..9f8993fa0ec 100644 --- a/test/metabase/lib/field_test.cljc +++ b/test/metabase/lib/field_test.cljc @@ -1251,3 +1251,34 @@ (lib/add-field -1 (second columns)) (lib.util/query-stage -1) :fields))))))) + +(deftest ^:parallel find-visible-column-for-ref-test + (testing "precise references" + (doseq [query-var [#'lib.tu/query-with-expression + #'lib.tu/query-with-join-with-explicit-fields + #'lib.tu/query-with-source-card] + :let [query @query-var] + col (lib/visible-columns query) + :let [col-ref (lib/ref col)]] + (testing (str "ref " col-ref " of " (symbol query-var)) + (is (= (dissoc col :lib/source-uuid) + (dissoc (lib/find-visible-column-for-ref query col-ref) :lib/source-uuid)))))) + (testing "reference by ID instead of name" + (let [query lib.tu/query-with-source-card + col-ref [:field + {:lib/uuid "ae24a9b0-cbb5-40b6-bace-c8a5ac6a7e42" + :base-type :type/Integer + :effective-type :type/Integer} + (meta/id :checkins :user-id)]] + (is (=? {:lib/type :metadata/column + :base-type :type/Integer + :semantic-type :type/FK + :name "USER_ID" + :lib/card-id 1 + :lib/source :source/card + :lib/source-column-alias "USER_ID" + :effective-type :type/Integer + :id (meta/id :checkins :user-id) + :lib/desired-column-alias "USER_ID" + :display-name "User ID"} + (lib/find-visible-column-for-ref query col-ref)))))) -- GitLab