// DataType helpers (port of parts of sqlglot/expressions/datatypes.py).
///|
/// `DataType(this=dtype)` (Python `DType.into_expr()` / `DataType.build(dtype)`).
pub fn datatype_of(dtype : DType) -> Expr {
mk1(DataType, dtype)
}
///|
/// `DataType.build(dtype, **kwargs)` for a `DType`.
pub fn datatype_build(
dtype : DType,
kwargs? : ArrayView[(String, &IntoValue)] = [],
) -> Expr {
let dt = datatype_of(dtype)
for kv in kwargs {
dt.set(kv.0, kv.1)
}
dt
}
///|
/// Python `DType.into_expr()`.
pub fn DType::into_expr(self : DType) -> Expr {
datatype_of(self)
}
///|
/// The `DType` stored in a DataType's `this`, if it's a plain type.
pub fn Expr::datatype_this(self : Expr) -> DType? {
match self.args.get("this") {
Some(DT(d)) => Some(d)
_ => None
}
}
///|
/// `DataType.is_type(*dtypes)` for plain `DType`s.
pub fn datatype_is_type(dt : Expr, dtypes : ArrayView[DType]) -> Bool {
let this = dt.datatype_this()
for d in dtypes {
let matches = if this == Some(DType::USERDEFINED) || d == DType::USERDEFINED {
dt == datatype_of(d)
} else {
this == Some(d)
}
if matches {
return true
}
}
false
}
///|
/// `DataType.is_type(other)` for a DataType expression `other`.
pub fn datatype_is_type_expr(dt : Expr, other : Expr) -> Bool {
let this = dt.datatype_this()
let other_this = other.datatype_this()
if !other.list("expressions").is_empty() ||
this == Some(DType::USERDEFINED) ||
other_this == Some(DType::USERDEFINED) {
dt == other
} else {
match (dt.args.get("this"), other.args.get("this")) {
(Some(DT(a)), Some(DT(b))) => a == b
(None, None) => true
(Some(Node(a)), Some(Node(b))) => a == b
(Some(Str(a)), Some(Str(b))) => a == b
_ => false
}
}
}
///|
/// Python `Expr.is_type(*dtypes)`.
pub fn Expr::is_type(self : Expr, dtypes : ArrayView[DType]) -> Bool {
if self.kind.is_data_type() {
return datatype_is_type(self, dtypes)
}
if self.kind.is_cast() {
return match self.arg("to") {
Some(to) => to.is_type(dtypes)
None => false
}
}
match self.type_ {
Some(t) => datatype_is_type(t, dtypes)
None => false
}
}
///|
/// Python `Expr.is_type(data_type_expr)`.
pub fn Expr::is_type_expr(self : Expr, other : Expr) -> Bool {
if self.kind.is_data_type() {
return datatype_is_type_expr(self, other)
}
if self.kind.is_cast() {
return match self.arg("to") {
Some(to) => to.is_type_expr(other)
None => false
}
}
match self.type_ {
Some(t) => datatype_is_type_expr(t, other)
None => false
}
}