Middleware that resolves the Fields referenced by a query. | (ns metabase.query-processor.middleware.resolve-fields (:require [metabase.legacy-mbql.schema :as mbql.s] [metabase.lib.metadata :as lib.metadata] [metabase.lib.schema :as lib.schema] [metabase.lib.schema.id :as lib.schema.id] [metabase.lib.util.match :as lib.util.match] [metabase.query-processor.error-type :as qp.error-type] [metabase.query-processor.store :as qp.store] [metabase.util :as u] [metabase.util.i18n :refer [tru]] [metabase.util.malli :as mu])) |
(defn- resolve-fields-with-ids!
[metadata-providerable field-ids]
(lib.metadata/bulk-metadata-or-throw metadata-providerable :metadata/column field-ids)
(when-let [parent-ids (not-empty
(into #{}
(comp (map (fn [field-id]
(:parent-id (lib.metadata/field metadata-providerable field-id))))
(filter some?))
field-ids))]
(recur metadata-providerable parent-ids))) | |
(defmulti ^:private field-ids
{:arglists '([query])}
(fn [query]
(if (:lib/type query) ::pmbql ::legacy))) | |
(mu/defmethod field-ids ::pmbql :- [:set ::lib.schema.id/field]
[query :- ::lib.schema/query]
(into #{}
(lib.util.match/match (:stages query)
[:field _opts (id :guard pos-int?)]
id
;; stage metadata
{:lib/type :metadata/column, :id (id :guard pos-int?)}
id))) | |
(mu/defmethod field-ids ::legacy :- [:set ::lib.schema.id/field]
[query :- ::mbql.s/Query]
(into (set (lib.util.match/match (:query query) [:field (id :guard integer?) _] id))
(comp cat (keep :id))
(lib.util.match/match (:query query) {:source-metadata source-metadata} source-metadata))) | |
Resolve all field referenced in the | (defn resolve-fields
[query]
(let [ids (field-ids query)]
(try
(u/prog1 query
(let [metadata-providerable (if (:lib/type query)
query
(qp.store/metadata-provider))]
(resolve-fields-with-ids! metadata-providerable ids)))
(catch Throwable e
(throw (ex-info (tru "Error resolving Fields in query: {0}" (ex-message e))
{:field-ids ids
:query query
:type qp.error-type/qp}
e)))))) |