Malli schemas for string, temporal, number, and boolean literals. | (ns metabase.lib.schema.literal
(:require
#?@(:clj
([java-time.api :as t]))
#?@(:clj ([metabase.lib.schema.literal.jvm]))
[metabase.lib.schema.common :as common]
[metabase.lib.schema.expression :as expression]
[metabase.lib.schema.mbql-clause :as mbql-clause]
[metabase.util.malli.registry :as mr]
[metabase.util.time.impl-common :as u.time.impl-common])) |
(defmethod expression/type-of-method :dispatch-type/nil [_nil] :type/*) | |
(defmethod expression/type-of-method :dispatch-type/boolean [_bool] :type/Boolean) | |
#?(:clj
(defn- big-int? [x]
(or (instance? java.math.BigInteger x)
(instance? clojure.lang.BigInt x)))) | |
(mr/def ::integer
#?(:clj [:multi
{:dispatch big-int?}
[true :metabase.lib.schema.literal.jvm/big-integer]
[false :int]]
:cljs :int)) | |
(defmethod expression/type-of-method :dispatch-type/integer [_int] :type/Integer) | |
we should probably also restrict this to disallow NaN and positive/negative infinity, I don't know in what universe we'd want to allow those if they're not disallowed already. | (mr/def ::non-integer-real
#?(:clj [:or
:double
:metabase.lib.schema.literal.jvm/float
:metabase.lib.schema.literal.jvm/big-decimal]
:cljs :double)) |
(defmethod expression/type-of-method :dispatch-type/number [_non-integer-real] ;; `:type/Float` is the 'base type' of all non-integer real number types in [[metabase.types]] =( :type/Float) | |
TODO -- these temporal literals could be a little stricter, right now they are pretty permissive, you shouldn't be
allowed to have month | (mr/def ::string.date
[:re
{:error/message "date string literal"}
u.time.impl-common/local-date-regex]) |
(mr/def ::string.zone-offset
[:re
{:error/message "timezone offset string literal"}
u.time.impl-common/zone-offset-part-regex]) | |
(mr/def ::string.time
[:or
[:re
{:error/message "local time string literal"}
u.time.impl-common/local-time-regex]
[:re
{:error/message "offset time string literal"}
u.time.impl-common/offset-time-regex]]) | |
(mr/def ::string.datetime
[:or
[:re
{:error/message "local date time string literal"}
u.time.impl-common/local-datetime-regex]
[:re
{:error/message "offset date time string literal"}
u.time.impl-common/offset-datetime-regex]]) | |
(defmethod expression/type-of-method :dispatch-type/string
[s]
(condp mr/validate s
::string.datetime #{:type/Text :type/DateTime}
::string.date #{:type/Text :type/Date}
::string.time #{:type/Text :type/Time}
:type/Text)) | |
(mr/def ::date
#?(:clj [:or
[:time/local-date
{:error/message "instance of java.time.LocalDate"
:encode/serialize str}]
::string.date]
:cljs ::string.date)) | |
(mr/def ::time
#?(:clj [:or
{:doc/title "time literal"}
::string.time
[:time/local-time
{:error/message "instance of java.time.LocalTime"
:encode/serialize str}]
[:time/offset-time
{:error/message "instance of java.time.OffsetTime"
:encode/serialize str}]]
:cljs ::string.time)) | |
(mr/def ::datetime
#?(:clj [:or
::string.datetime
[:time/local-date-time
{:error/message "instance of java.time.LocalDateTime"
:encode/serialize str}]
[:time/offset-date-time
{:error/message "instance of java.time.OffsetDateTime"
:encode/serialize str}]
[:time/zoned-date-time
{:error/message "instance of java.time.ZonedDateTime"
:encode/serialize #(str (t/offset-date-time %))}]]
:cljs ::string.datetime)) | |
(mr/def ::temporal [:or ::date ::time ::datetime]) | |
these are currently only allowed inside | |
(mr/def ::string.year-month
[:re
{:error/message "year-month string literal"}
u.time.impl-common/year-month-regex]) | |
(mr/def ::string.year
[:re
{:error/message "year string literal"}
u.time.impl-common/year-regex]) | |
| (mr/def ::value.options
[:merge
[:ref ::common/options]
[:map
[:effective-type ::common/base-type]]]) |
[:value The schema itself does not currently enforce that the actual | (mbql-clause/define-mbql-clause :value
[:tuple
{:error/message "Value :value clause"}
#_tag [:= {:decode/normalize common/normalize-keyword} :value]
#_opts [:ref ::value.options]
#_value any?]) |
(mr/def ::literal [:or :nil :boolean :string ::integer ::non-integer-real ::temporal]) | |