(ns metabase.query-processor.middleware.desugar (:require [medley.core :as m] [metabase.legacy-mbql.predicates :as mbql.preds] [metabase.legacy-mbql.schema :as mbql.s] [metabase.legacy-mbql.util :as mbql.u] [metabase.lib.metadata :as lib.metadata] [metabase.lib.util.match :as lib.util.match] [metabase.query-processor.store :as qp.store] [metabase.util.malli :as mu])) | |
Add base type to fields with id that are missing it. It is necessary for correct function of [[metabase.legacy-mbql.util/desugar-is-empty-and-not-empty]]. | (defn- add-missing-field-base-types [query] (lib.util.match/replace query (field-clause :guard (fn [clause] (and (mbql.preds/Field? clause) (integer? (second clause)) (not (contains? (get clause 2) :base-type))))) (let [id (second field-clause) metadata (lib.metadata/field (qp.store/metadata-provider) id) {:keys [base-type]} metadata] (update field-clause 2 assoc :base-type base-type ::desugar-added-base-type true)))) |
(defn- remove-desugar-added-base-types [query] (lib.util.match/replace query (field-clause :guard (fn [clause] (and (mbql.preds/Field? clause) (integer? (second clause)) (get-in clause [2 ::desugar-added-base-type])))) (update field-clause 2 (comp not-empty #(dissoc % :base-type ::desugar-added-base-type))))) | |
(defn- desugar* [query] (lib.util.match/replace query (filter-clause :guard mbql.preds/Filter?) (mbql.u/desugar-filter-clause filter-clause) (temporal-extract-clause :guard mbql.preds/DatetimeExpression?) (mbql.u/desugar-temporal-extract temporal-extract-clause) (expression :guard mbql.preds/FieldOrExpressionDef?) (mbql.u/desugar-expression expression))) | |
(mu/defn desugar :- mbql.s/Query "Middleware that uses MBQL lib functions to replace high-level 'syntactic sugar' clauses like `time-interval` and `inside` with lower-level clauses like `between`. This is done to minimize the number of MBQL clauses individual drivers need to support. Clauses replaced by this middleware are marked `^:sugar` in the MBQL schema." [query] ;; Base types are added to field options for integer id fields that are missing those. Then original desugar ;; is performed. Later those base types (added for desugaring purposes [expanding is-empty, not-empty]) are removed. (m/update-existing query :query (comp remove-desugar-added-base-types desugar* add-missing-field-base-types))) | |