This namespace handles parameters that are operators. {:type :number/between :target [:dimension [:field 26 {:source-field 5}]] :value [3 5]} | (ns metabase.driver.common.parameters.operators (:require [metabase.legacy-mbql.schema :as mbql.s] [metabase.legacy-mbql.util :as mbql.u] [metabase.lib.schema.parameter :as lib.schema.parameter] [metabase.query-processor.error-type :as qp.error-type] [metabase.util.i18n :refer [tru]] [metabase.util.malli :as mu])) |
(mu/defn- operator-arity :- [:maybe [:enum :unary :binary :variadic]] [param-type] (get-in lib.schema.parameter/types [param-type :operator])) | |
(defn- operator-options-fn
[param-type]
(get-in lib.schema.parameter/types [param-type :options-fn]
;; Default is to conj on the end if options are provided.
(fn [clause options]
(cond-> clause
options (conj options))))) | |
Returns whether param-type is an "operator" type. | (defn operator? [param-type] (boolean (operator-arity param-type))) |
(mu/defn- verify-type-and-arity
[field param-type param-value]
(letfn [(maybe-arity-error [n]
(when (not= n (count param-value))
(throw (ex-info (format "Operations Invalid arity: expected %s but received %s"
n (count param-value))
{:param-type param-type
:param-value param-value
:field-id (second field)
:type qp.error-type/invalid-parameter}))))]
(condp = (operator-arity param-type)
:unary
(maybe-arity-error 1)
:binary
(maybe-arity-error 2)
:variadic
(when-not (sequential? param-value)
(throw (ex-info (tru "Invalid values provided for operator: {0}" param-type)
{:param-type param-type
:param-value param-value
:field-id (second field)
:type qp.error-type/invalid-parameter})))
(throw (ex-info (tru "Unrecognized operation: {0}" param-type)
{:param-type param-type
:param-value param-value
:field-id (second field)
:type qp.error-type/invalid-parameter}))))) | |
(mu/defn to-clause :- mbql.s/Filter
"Convert an operator style parameter into an mbql clause. Will also do arity checks and throws an ex-info with
`:type qp.error-type/invalid-parameter` if arity is incorrect."
[{param-type :type [a b :as param-value] :value [_ field :as _target] :target options :options :as _param}]
(verify-type-and-arity field param-type param-value)
(let [field' (mbql.u/wrap-field-id-if-needed field)
opts-fn (operator-options-fn param-type)]
(case (operator-arity param-type)
:binary (opts-fn [(keyword (name param-type)) field' a b] options)
:unary (opts-fn [(keyword (name param-type)) field' a] options)
:variadic (opts-fn (into [(keyword (name param-type)) field'] param-value) options)
(throw (ex-info (format "Unrecognized operator: %s" param-type)
{:param-type param-type
:param-value param-value
:field-id (second field)
:type qp.error-type/invalid-parameter}))))) | |