diff --git a/crates/expr/src/lib.rs b/crates/expr/src/lib.rs index 4860bdc882e..6d66c26c2de 100644 --- a/crates/expr/src/lib.rs +++ b/crates/expr/src/lib.rs @@ -145,15 +145,19 @@ pub(crate) fn type_expr(vars: &Relvars, expr: SqlExpr, expected: Option<&Algebra } /// Is this type compatible with this binary operator? -fn op_supports_type(_op: BinOp, t: &AlgebraicType) -> bool { - t.is_bool() - || t.is_integer() - || t.is_float() - || t.is_string() - || t.is_bytes() - || t.is_identity() - || t.is_connection_id() - || t.is_timestamp() +fn op_supports_type(op: BinOp, ty: &AlgebraicType) -> bool { + match (ty, op) { + (AlgebraicType::Sum(st), BinOp::Eq | BinOp::Ne) if st.is_simple_enum() => true, + _ if ty.is_bool() => true, + _ if ty.is_integer() => true, + _ if ty.is_float() => true, + _ if ty.is_string() => true, + _ if ty.is_bytes() => true, + _ if ty.is_identity() => true, + _ if ty.is_connection_id() => true, + _ if ty.is_timestamp() => true, + _ => false, + } } /// Parse an integer literal into an [AlgebraicValue] @@ -222,6 +226,14 @@ pub(crate) fn parse(value: &str, ty: &AlgebraicType) -> anyhow::Result st.get_variant_simple(value).ok_or_else(|| anyhow!("{value} is not a valid {}", fmt_algebraic_type(&ty)))?.0, + _ => unreachable!("ty.is_simple_enum() is true"), + } + )) + }; let to_i256 = |decimal: &BigDecimal| { i256::from_str_radix( // Convert to decimal notation @@ -342,6 +354,7 @@ pub(crate) fn parse(value: &str, ty: &AlgebraicType) -> anyhow::Result to_bytes(), t if t.is_identity() => to_identity(), t if t.is_connection_id() => to_connection_id(), + t if t.is_simple_enum() => to_simple_enum(), t => bail!("Literal values for type {} are not supported", fmt_algebraic_type(t)), } } diff --git a/crates/sats/src/algebraic_type.rs b/crates/sats/src/algebraic_type.rs index 10e48dfd599..32cf5a726e1 100644 --- a/crates/sats/src/algebraic_type.rs +++ b/crates/sats/src/algebraic_type.rs @@ -201,6 +201,11 @@ impl AlgebraicType { matches!(self, Self::Sum(p) if p.is_empty()) } + /// Returns whether this type is a simple enum type. + pub fn is_simple_enum(&self) -> bool { + matches!(self, Self::Sum(p) if p.is_simple_enum()) + } + /// If this type is the standard option type, returns the type of the `some` variant. /// Otherwise, returns `None`. pub fn as_option(&self) -> Option<&AlgebraicType> {